1

根据 GraphQL 规范https://graphql.github.io/graphql-spec/draft/#sec-Input-Objects

输入对象文字或无序映射不得包含名称未由该输入对象类型的字段定义的任何条目,否则必须抛出错误。

假设我有一个项目,该项目有一个名为买家的用户,其架构如下

type Buyer {
     id: ID!
     name: String!
     address: String!
     email: String!
}

现在我可以为它写一个石墨烯模式

class BuyerType(DjangoObjectType):
    class Meta:
        model = Buyer

并为此做一个突变

class BuyerInput(graphene.InputObjectType):
    name = graphene.String(required=False, default_value='')
    address = graphene.String(required=False, default_value='')
    email = graphene.String(required=False, default_value='')


class BuyerMutation(graphene.Mutation):
    """
    API to create applicant
    """
    class Arguments:
        buyer_data = BuyerInput(required=True)


    buyer = graphene.Field(BuyerType)
    ok = graphene.Boolean()

    def mutate(self, info, buyer_data=None):
           buyer = Buyer(name=buyer.name, address=buyer.address, email=buyer.email)
           buyer.save()
           return BuyerMutation(buyer=buyer, ok=True)

并编写解析器函数以及查询和变异类。到目前为止非常基本的东西。

现在要创建一个新的买家,我只是称之为突变

mutation {
   createBuyer(
           name: "New Buyer"
           address: "Earth"
           email: "abc@example.com"
  ) {
      ok
  }
}

但是,如果我通过一个名为电话的附加字段

mutation {
   createBuyer(
           name: "New Buyer"
           address: "Earth"
           email: "abc@example.com"
           phone: 8541345474
  ) {
      ok
  }
}

出现Unknown field 'phone'错误,这是可以理解的。

但我想让前端开发人员的流程更容易。他们可以传递一个包含这三个字段以及其他可能来自表单提交的参数的字典,而不是在突变参数中提及每个字段,然后在后端读取字典并仅提取我需要的字段,就像使用 REST API 完成的一样。

如果这是可能的,那么我该如何实现呢?

4

1 回答 1

0

我们可以获取BuyerInput使用inspect模块的类属性,然后组装参数字典,使其忽略不属于此类属性的键。说,我们有一个包含createBuyer存储在变量中的参数的字典kwargs,这可能如下所示:

import inspect


members = inspect.getmembers(BuyerInput, lambda a: not(inspect.isroutine(a)))
attributes = [
    tup[0] 
    for tup in members 
    if not tup[0].startswith("_")
]

kwargs = {
    key: value
    for key, value in kwargs.items()
    if key in attributes
}
于 2019-11-12T11:15:49.630 回答