Skip to content

ObjectType resolving fields from dicts or objects #798

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ilyakitaev opened this issue Jul 12, 2018 · 8 comments
Closed

ObjectType resolving fields from dicts or objects #798

ilyakitaev opened this issue Jul 12, 2018 · 8 comments

Comments

@ilyakitaev
Copy link

ilyakitaev commented Jul 12, 2018

Hi! There is an example code:

class Photo(graphene.ObjectTypet):
  
      id = graphene.ID()
      url = graphene.String()
      fileName = graphene.String()
      extension = graphene.String()
  
  
class User(graphene.ObjectTypet):
  
      _id = graphene.ID()
      name = graphene.String()
      photos = graphene.List(Photo)

class Query(graphene.ObjectType):
      user = graphene.Field(User, dict(_id=graphene.String(required=True)))
  
      async def resolve_user(self, info, _id):
          user = await db.users.find_one(dict(_id=_id))
          # do the simple filted
          resolved_fileds = {f: user[f]
                           for f in User._meta.fields}
          user = User(**resolved_fileds) if user else None
          return user

The result is

{
  "data": {
    "user": {
      "Id": "1",
      "name": "Test User",
      "photos": [
        {
          "id": null,
          "fileName": null
        }        
      ]
    }
  }
}

Field "photos" not initialized in init. In argument "photos" I got just list with dicts. I know that I can to this serialization by myself, but maybe it's already implemented?

@ilyakitaev ilyakitaev changed the title ObjectType initialisation ObjectType initialization Jul 12, 2018
@jkimbo
Copy link
Member

jkimbo commented Jul 12, 2018

What does the photos field that you get back from db.users.find_one(dict(_id=_id)) look like? By default Graphene uses getattr to pick off fields from a data object.

@ilyakitaev
Copy link
Author

@jkimbo as I say it's a list of dicts. I can convert it to list of Photos() manually, but the question is there any already implemented way to fill ObjectType with nested fields from dictionary or I have to implement it by myself.

@jkimbo
Copy link
Member

jkimbo commented Jul 14, 2018

You could change the default resolver on the Photo Object type like this:

from graphene.types.resolver import dict_resolver

class Photo(graphene.ObjectType):
	class Meta:
		default_resolver = dict_resolver
      
	id = graphene.ID()
    url = graphene.String()
    fileName = graphene.String()
    extension = graphene.String()

@ilyakitaev
Copy link
Author

Thanks, @jkimbo. That's what I was looking for. I think that it would be in docs.

@jkimbo
Copy link
Member

jkimbo commented Jul 24, 2018

Yep I agree. A PR would be welcome if you have the time

@jkimbo jkimbo closed this as completed Jul 24, 2018
@jkimbo jkimbo reopened this Jul 24, 2018
@jkimbo jkimbo changed the title ObjectType initialization ObjectType resolving fields from dicts or objects Jul 24, 2018
@jkimbo
Copy link
Member

jkimbo commented Jul 24, 2018

Also I have a PR #638 which should mean by default graphene would handle dicts and objects transparently

@saffrydaffry
Copy link

I'm surprised this wasn't in the docs, i'd spent so much unnecessary effort explicitly resolving dicts... please update the docs, this is an expected behavior of graphql. thanks

@y0urself
Copy link

Is it correct, that the class Meta: "feature" is only for Python 2?

Is there any other workaround to set the default_resolver when using Python 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants