石墨烯Django-具有一对多关系外键的变异

时间:2018-11-20 10:35:27

标签: django django-models graphql graphene-python

我想知道如何正确创建创建django模型的突变:

class Company(models.Model):

    class Meta:
        db_table = 'companies'
        app_label = 'core'
        default_permissions = ()

    name = models.CharField(unique=True, max_length=50, null=False)
    email = models.EmailField(unique=True, null=False)
    phone_number = models.CharField(max_length=13, null=True)
    address = models.TextField(max_length=100, null=False)
    crn = models.CharField(max_length=20, null=False)
    tax = models.CharField(max_length=20, null=False)
    parent = models.ForeignKey('self', null=True, on_delete=models.CASCADE)
    currency = models.ForeignKey(Currency, null=False, on_delete=models.CASCADE)
    country = models.ForeignKey(Country, null=False, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

如您所见,有三个外键。对于模型货币国家父母(自己)公司DjangoObjectType 看起来很简单:

class CompanyType(DjangoObjectType):
    class Meta:
        model = Company

最后,我的变异类 CreateCompany 具有货币国家/地区自我(父母),定义为{{ 1}}:

graphene.Field()

当我要启动django服务器时,会出现Assertion错误。

class CompanyInput(graphene.InputObjectType):
    name = graphene.String(required=True)
    email = graphene.String(required=True)
    address = graphene.String(required=True)
    crn = graphene.String(required=True)
    tax = graphene.String(required=True)
    currency = graphene.Field(CurrencyType)
    country = graphene.Field(CountryType)
    parent = graphene.Field(CompanyType)
    phone_number = graphene.String()


class CreateCompany(graphene.Mutation):
    company = graphene.Field(CompanyType)

    class Arguments:
        company_data = CompanyInput(required=True)

    @staticmethod
    def mutate(root, info, company_data):
        company = Company.objects.create(**company_data)
        return CreateCompany(company=company)

很长一段时间以来,我一直在寻找一些针对一对多外键的优秀教程,因此,如果有人清楚地知道如何实现此解决方案,我将非常高兴。

PS:也请您向我展示GraphQL查询的示例,这样我知道如何称呼该突变?非常感谢。

1 个答案:

答案 0 :(得分:0)

对于那些仍在寻找答案的人。

class CompanyInput(graphene.InputObjectType):
    name = graphene.String(required=True)
    email = graphene.String(required=True)
    address = graphene.String(required=True)
    crn = graphene.String(required=True)
    tax = graphene.String(required=True)
    currency = graphene.Field(CurrencyInput)
    country = graphene.Field(CountryInput)
    parent = graphene.Field(CompanyInput)
    phone_number = graphene.String()

class CurrencyInput(graphene.InputObjectType):
    name = graphene.String()
    code = graphene.String()
    character = graphene.String()

class CountryInput(graphene.InputObjectType):
    name = graphene.String()
    code = graphene.String()


class CreateCompany(graphene.Mutation):
    company = graphene.Field(CompanyType)

    class Arguments:
        company_data = CompanyInput(required=True)

    @staticmethod
    def mutate(root, info, company_data):
        company = Company.objects.create(**company_data)
        return CreateCompany(company=company)

如您所见,我只是将CompanyType,CurrencyType和CountryType对象替换为输入对象,因为Input对象指定INPUT来查询(请求)哪种用户类型。

类型对象,指定成功完成所有操作后突变返回的返回对象。因此,当您仅查看类CreateCompany时,company是对象,当成功完成更改后将返回该对象(Is CompanyType对象),因为我们创建了Company并希望对象Company的响应。

作为Arguments类,有CompanyInput,它具有嵌套输入,例如货币或国家或自身(其类似于对象中的对象)。

静态方法mutate将调用Django创建函数,并将此创建的对象分配给我们的公司对象,该对象为CompnyType,并且将是该响应。

(当然,当您要在创建之前和之后实现一些业务逻辑时,当然可以调用创建函数以外的其他函数,但是变异方法必须返回特定对象或被定义为响应的一个或多个对象。当然可以有更多的对象或对象列表。仅取决于您。)