【问题标题】:Mutations - batch creation of objects突变 - 批量创建对象
【发布时间】:2017-10-19 14:38:01
【问题描述】:

我想用石墨烯一口气创造很多人。 文档只提到了这样创建一个人的方法:

class CreatePerson(graphene.Mutation):
class Input:
    name = graphene.String()
    age = graphene.Int()

ok = graphene.Boolean()
person = graphene.Field(lambda: Person)

@staticmethod
def mutate(root, args, context, info):
    person = Person(name=args.get('name'), age=args.get('age'), mobile=args.get('mobile'))
    ok = True
    return CreatePerson(person=person, ok=ok)

有什么方法可以完成吗?

【问题讨论】:

  • 仅供参考,您可以发布您的解决方案作为答案并接受它,以便追随您的人可以轻松看到最终解决方案。

标签: graphql graphene-python


【解决方案1】:

让你的变异输入一个列表并返回一个创建人的列表。像这样的:

class CreatePerson(graphene.Mutation):
    class Input:
        name = graphene.List(graphene.String)

    ok = graphene.Boolean()
    people = graphene.List(Person)

    @staticmethod
    def mutate(root, args, context, info):
        people = [Person(name=name) for name in args.get('name)]
        ok = True
        return CreatePerson(people=people, ok=ok)

【讨论】:

  • 太棒了!但是我该如何处理多个领域。例如。此人的姓名、地址和年龄?
  • 您可以有复杂的输入类型,请参阅文档:docs.graphene-python.org/en/latest/types/mutations
  • 嗨 Jan,我使用 InputObject 并且它可以工作,但数据没有保存到数据库中。你介意帮忙吗?非常感谢!
【解决方案2】:

除了使用创建对象列表的突变之外,您还可以调用在一个 GraphQL 请求中多次创建一个对象的突变。这是使用GraphQL Aliases 完成的:

mutation {
  c001: createPerson(
    name: "Donald Duck"
    age: 42
  ) {
    id
  }

  c002: createPerson(
    name: "Daisy Duck"
    age: 43
  ) {
    id
  }

  c003: createPerson(
    name: "Mickey Mouse"
    age: 44
  ) {
    id
  }
}

【讨论】:

  • FAQ 的链接已失效。
  • 列表批次还是别名批次哪个更好?
【解决方案3】:

接收输入列表,创建所有实例并全部返回

模型节点/类型应该像-

class UserType(DjangoObjectType):

    class Meta:
        model = User
        interfaces = (CustomGrapheneNode, )
        filter_fields = {}
        only_fields = (
            'name',
            'email'
        )

定义输入字段

class UserInput(graphene.InputObjectType):
    name = graphene.String(required=True)
    password = graphene.String(required=True)

变异类

class CreateUser(graphene.Mutation):
    users = graphene.List(UserType)

    class Input:
        data = graphene.List(UserInput)

    Output = graphene.List(UserType)

    def mutate(self, info, data):
        users = []
        for item in data:
            user = User.objects.create(name=data['name'], 
                                       password=data['password'])
            users.append(user)
        return users

使这个突变可以被主模式调用

class Mutation():
    create_user = CreateUser.Field()

变异查询视图将是 -

mutation{
    createUser(data:[{name:"john", password:"1234"},
                     {name:"john", password:"1234"}]) {
        user{
            name
        }
    }    
}

【讨论】:

  • 很好的解决方案。只需添加您可以在 mutate() 函数中使用 bulk_create() 方法,如文档中所述:docs.djangoproject.com/en/3.2/ref/models/querysets
  • 如果其他人尝试此答案并且您遇到错误,请在 mutate 函数中更改数据中的项目: user = User.objects.create(name=data['name'], password =data['password']) 改为:对于数据中的项目:user = User.objects.create(name=item['name'], password=item['password'])
【解决方案4】:

我可以根据Jan Hančič的答案找出解决方案

在这种情况下使用一种称为graphene.InputObjectType 的类型

解决办法可以是

class PersonInput(InputObjectType):
    name = graphene.String()
    age = graphene.Int()

class CreatePeople(graphene.Mutation):
    class Input:
       people = graphene.List(PersonInput)

    people = graphene.List(lambda: Person)

    @staticmethod
    def mutate(root, args, context, info):
        people = [Person.objects.create(name=person.name, age=person.age) for person in args.get('people')]
        return CreatePeople(people=people)

【讨论】:

猜你喜欢
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
相关资源
最近更新 更多