如何使用Graphene GraphQL解决嵌套在另一个类型中的字段?

12

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

每篇文章都有一个作者,并且查询是在模式文件中构建的。

我正在尝试从Post内部解析 Author,而不必在Post中声明一个解析器函数,因为Author已经有了一个自己声明的解析器函数。下面的代码可以工作,但是我必须从Post类型中引用resolve_author,这似乎不正确。我认为Graphene应该直接将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)

作者.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 }。 - Anoop P S
1个回答

2

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没有问题,因为它会被边缘解析器过滤掉。你说得对,帖子和作者之间没有关系,所以我不应该指望帖子自动获取作者信息,但应该有更好的方法来解决这个问题…… - jpenna
1
我曾与 Django ORM 合作,找到的最佳方法是在根解析器中获取所有需要解析的数据(这里有一个很好的库-graphene-django-optimizer),然后将此数据传递给解析器,以便它们获得完整对象,无需访问数据库。相关字段(如“帖子”作者)已在根解析器中检索,我所要做的就是将数据库字段映射为“graphql”类型。 - donnyyy
1
这很有道理。我在这里尝试了一些东西,试用后我会更新这个帖子。 - jpenna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接