【问题标题】:Return any data from a query using GraphQL, Graphene and Python使用 GraphQL、Graphene 和 Python 从查询中返回任何数据
【发布时间】:2020-03-22 04:10:48
【问题描述】:

我收到以下错误:

{
  "errors": [
    {
      "message": "Unknown argument \"project_id\" on field" +
                 \"get_project_detail_summary\" of type \"Query\".",
      "locations": [
        {
          "line": 2,
          "column": 30
        }
      ]
    }
  ]
}

使用以下查询:

query GetProjectDetailSummary($project_id: Int) {
  get_project_detail_summary(project_id: $project_id) {
    comments {
      ... on ManagerCommentNode {
        id
        text
        created
      }
      ... on VendorCommentNode {
        id
        text
        created
      }
      ... on TenantCommentNode {
        id
        text
        created
      }
    }
  }
}

使用以下后端代码,我怎样才能到达断点?,或者我如何发回给定数字的自定义数据?:

class CommentsUnion(graphene.types.union.Union):
    class Meta:
        name = 'CommentsUnion'
        types = (ManagerCommentNode, VendorCommentNode, TenantCommentNode, )


class ProjectSummaryInput(graphene.InputObjectType):
    project_id = graphene.Int()


class ProjectSummaryNode(graphene.ObjectType):
    Input = ProjectSummaryInput

    project_id = graphene.Int()
    comments = graphene.List(CommentsUnion)

    @classmethod
    def resolve_comments(self, *args, **kwargs):
        import pdb;pdb.set_trace()
        return ProjectSummary.select_related('comments').objects.filter(comments__created__lt=dt)

class Query(graphene.ObjectType):
    get_project_detail_summary = Field(ProjectSummaryNode)

【问题讨论】:

    标签: graphql graphene-python graphene-django


    【解决方案1】:

    关于错误。

    请务必在 graphene.Fieldget_project_detail_summary 中添加一个 kwarg(例如,本例中的 project_id,这是“字段上的未知参数”错误的原因)。

    像这样:

    class Query(graphene.ObjectType):
        get_project_detail_summary = Field(ProjectSummaryNode, # see below for example
                                           project_id=graphene.Int() # kwarg here
                                          )
    
        def resolve_get_project_detail_summary(self, info, **kwargs):
            return ProjectSummary.objects.get(id=kwargs.get('project_id'))
    

    关于返回任何数据。

    这是一种方式(返回 graphene.String ),但它通过将所有内容放入字符串中来取消输入响应:

    
    from django.core.serializers.json import DjangoJSONEncoder
    
    class ProjectSummaryRecentUpdatesNode(graphene.ObjectType):
        Input = ProjectSummaryInput
        recent_updates = graphene.String()
    
        def resolve_recent_updates(self, resolve, **kwargs):
            instance = Project.objects.get(id=resolve.variable_values.get("project_id"))
            things = instance.things.all()
            # these are all from different models, and the list is a bit longer than this.
            querysets = (
                ("scheduled", get_scheduled(things, resolve, **kwargs)),
                ("completed", get_completed(things, resolve, **kwargs)),
                ("invoices", get_invoices(things, resolve, **kwargs)),
                ("expenditures", get_expenditures(things, resolve, **kwargs)),
                ("comments", get_comments(things, resolve, **kwargs)),
                ("files", get_files(things, resolve, **kwargs)),
            )
            recent_updates = []
            for update_type, qs in querysets:
                for item in qs:
                    item.update(
                        {
                            "recent_update_type": update_type
                        }
                    )
                    recent_updates.append(item)
            return json.dumps(recent_updates, cls=DjangoJSONEncoder)
    

    在前端,使用import { Query } from "react-apollo"; 元素,我们可以JSON.parse 字段...其中包含“任何”(json 序列化)数据:

    <Query
        query={GET_PROJECT_DETAIL_SUMMARY_RECENT_UPDATES}
        fetchPolicy="network-only"
        variables={{ project_id: this.props.projectId }}
    >
        {({ loading, error, data }: QueryResult) => {
            if (
                data &&
                data.get_project_detail_summary_recent_updates &&
                data.get_project_detail_summary_recent_updates.recent_updates
            ) {
                console.log(JSON.parse(data.get_project_detail_summary_recent_updates.recent_updates))
            }    
        }}
    </Query>
    

    旁注:

    如果没有大量数据类型列表,请创建一个类似 Union 的对象,其中包含不同模型所需的所有字段,或者创建一个实际的 Union,这似乎是正确的方法,因为类型是没有丢失:

    class ProjectSummaryNode(graphene.ObjectType):
        # from FileNode graphene.ObjectType class
        file__id = graphene.Int()
        file__brief_description = graphene.String()
        file_count = graphene.Int()
        last_file_created = graphene.String()
        last_file = graphene.String()
    
        # from UploaderNode graphene.ObjectType class
        uploader__first_name = graphene.String()
        uploader__last_name = graphene.String()
    
        # from CommentNode graphene.ObjectType class
        comment = graphene.String()
    
        class Meta:
            name = "ProjectSummaryNode"
            # example of Union, the above fields would be commented out, as they are part of 
            # the different graphene.ObjectType classes, and this line below would be uncommented
            # types = ( FileNode, UploaderNode, CommentNode, )
    

    仍然愿意接受有关更好方法的建议。

    【讨论】:

      猜你喜欢
      • 2020-07-05
      • 2021-09-12
      • 2017-11-19
      • 2018-05-15
      • 2023-03-12
      • 1970-01-01
      • 2019-08-15
      • 2022-12-29
      • 2019-03-30
      相关资源
      最近更新 更多