【问题标题】:Graphene Django - Mutation with one to many relation foreign keyGraphene Django - 具有一对多关系外键的突变
【发布时间】:2019-04-22 18:50:03
【问题描述】:

我想知道如何正确地创建突变来创建这个 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)

如您所见,共有三个外键。对于模型 CurrencyCountryParent(self)公司 DjangoObjectType 看起来很简单,如下所示:

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

最后我的变异类 CreateCompanyCurrencyCountrySelf(Parent) 定义为 @987654323 @:

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)

当我想启动 django 服务器时,会引发断言错误。

AssertionError: CompanyInput.currency field type must be Input Type but got: CurrencyType.

长期以来,我一直在为一对多外键寻找一些很好的教程,所以如果有人知道如何实现这个解决方案,我会很高兴。

PS:请你也给我看一下 GraphQL 查询的例子,这样我就知道如何调用这个突变了?非常感谢。

【问题讨论】:

  • 您找到解决此问题的方法了吗?
  • @KeykoYume 是的。到 graphene.Field 去 InputType 而不是 Type 对象。如您所见,CompanyInput 类。您需要做的就是将例如 graphene.Field(CurrencyType) 更改为 graphene.Field(CurrencyInput)。与 CompanyInput 相同的货币类。
  • 能否请您写下答案以及您为CurrencyInput 定义的内容以及相关的graphql 查询?由于外键字段,我在创建突变时遇到了麻烦,我已经尝试实现您的上述方法,但显然,我缺少一些重要的东西。
  • 你们有没有人设法让这个工作?很想看看它的一个例子。

标签: django django-models graphql graphene-python


【解决方案1】:

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

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 对象),因为我们创建了公司并且我们想要对象公司的响应。

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

静态方法 mutate 将调用 Django 创建函数,这个创建的对象将分配给我们的公司对象 CompnyType,这将是那个响应。

(当然,当您想在创建之前和之后实现一些业务逻辑时,您可以调用另一个函数而不是创建,但是变异方法必须返回一个或多个特定的对象,这些对象曾经或被定义为响应。对我来说,在 CreateCompany 类中的公司。当然可以有更多对象或对象列表。这仅取决于您。)

【讨论】:

  • 能否请您展示您的查询示例?我想知道您是如何在突变查询中提供 ForeignKey 输入的
  • 嗨。可以通过两种方式处理外键。首先像上面的例子一样,货币、国家和父母都在模型外键中,但在那个例子中,您将在表中创建新记录并将该记录作为 FK 分配给 Company 对象。第二个例子(我希望你想要)是 FK 对象已经在表中创建,你只想将它分配给 Company 对象。它非常相似。例如,将货币作为 FK,它将在输入中像:currency_id = graphene.Int() 并且在变异中,您只需提供与货币对象的 FK 对应的数字。
  • 是的,谢谢。我正在考虑将整个外来对象传递给突变查询,而不是仅传递 ID,关于 GraphQL InputType(认为保持它们一致),但后来我决定避免这种奇怪的事情并只使用 ID。
  • 哦,所以即使使用 InputObjectType 我们只需要提供所需对象的 ID,然后以某种方式获取它以便能够分配它?
猜你喜欢
  • 2021-02-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2011-11-15
  • 2011-12-06
  • 2023-03-08
  • 2012-07-22
  • 1970-01-01
相关资源
最近更新 更多