【问题标题】:How to resolve a Field nested in another Type using Graphene GraphQL?如何使用 Graphene GraphQL 解析嵌套在另一个类型中的字段?
【发布时间】:2019-12-14 23:02:36
【问题描述】:

我有 3 个文件:authors.pyposts.pyschema.py

帖子有一个作者,查询构建在架构文件中。

我正在尝试从Post 内部解析Author,而不在Post 中声明解析器函数,因为Author 已经声明了自己的解析器函数。以下代码有效,但我必须从 Post 类型内部引用 resolve_author ,这似乎不正确。我认为石墨烯应该将parent 参数直接传递给Author,不是吗?

如果我没有在Post 类型中为author 设置解析器,它只会返回null

schema.py

import graphene
from graphql_api import posts, authors


class Query(posts.Query, authors.Query):
    pass


schema = graphene.Schema(query=Query)

authors.py

from graphene import ObjectType, String, Field


class Author(ObjectType):
    id = ID()
    name = String()


class Query(ObjectType):
    author = Field(Author)

    def resolve_author(parent, info):
        return {
            'id': '123',
            'name': 'Grizzly Bear',
            'avatar': '#984321'
        }

posts.py

from graphene import ObjectType, String, Field
from graphql_api import authors


class Post(ObjectType):
    content = String()
    author = Field(authors.Author)

    def resolve_author(parent, info):
        # I'm doing like this and it works, but it seems wrong. 
        # I think Graphene should be able to use my resolver 
        # from the Author automatically...
        return authors.Query.resolve_author(parent,
                                            info, id=parent['authorId'])


class Query(ObjectType):
    post = Field(Post)

    def resolve_post(parent, info):
        return {
            'content': 'A title',
            'authorId': '123',
        }

【问题讨论】:

  • 我也有同样的问题。它在本地工作正常,但在实时服务器中显示在解析器错误中找不到帖子。 .架构类型为 User{ id:Int firstname:string lastname:string post:Post }

标签: python graphql graphene-python


【解决方案1】:

Query.resolve_author 不会被调用,因为它与Post 对象之间没有关系。

我建议如下:

from graphene import ObjectType, String, Field
from graphql_api import authors


class Post(ObjectType):
    content = String()
    author = Field(authors.Author)

    def resolve_author(self, info):
        # author_utils.get_author returns complete object that will be passed into Author's object resolvers (if some fields are missing)
        # I suggest returning here an object from database so author resolver would extract another fields inside
        # But it may be just an id that will be passed in Author resolvers as first arguments
        return author_utils.get_author(post_id=self.id)


class Query(ObjectType):
    post = Field(Post)

    def resolve_post(parent, info):
        # Here you shouldn't author_id as it's not defined in type 
        return {
            'content': 'A title',
        }

Author(假设author_utils.get_author 只返回一个id):

class Author(ObjectType):
    id = ID()
    name = String()

    def resolve_id(id, info):
        # root here is what resolve_author returned in post. Be careful, it also will be called if id is missing after Query.resolve_author
        return id

    def resolve_name(id, info):
        # same as resolve_id
        return utils.get_name_by_id(id)

【讨论】:

  • 这种方式效率不高,我得先取帖子再取帖子才能得到作者。从字段解析器返回author_id 没有问题,因为它将被边缘解析器过滤。您是对的,Post 和 Author 之间没有关系,所以我不应该期望 Post 自动获取 Author,但是应该有更好的方法来解决这个问题......
  • 我使用 django orm,我发现最好的方法是获取我必须在根解析器中解析的所有数据(有一个很棒的库 - graphene-django-optimizer),然后将这些数据传递给解析器,所以他们得到完整的对象并且不必访问 db.相关字段(如Post 中的Author)已经在根解析器中获取,我唯一要做的就是将db-fields 映射到graphql 类型。
  • 这是有道理的。我在这里尝试了一些东西,我会在尝试后更新此线程。
猜你喜欢
  • 2017-12-18
  • 2021-07-28
  • 2020-08-31
  • 2021-07-20
  • 2019-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多