【问题标题】:Nested mutation Django + GraphQL嵌套突变 Django + GraphQL
【发布时间】:2021-04-09 00:03:49
【问题描述】:

我是 Django/Graphql/Graphene 的新手,正在努力编写具有多个外键和多对多关系的嵌套突变。我已经阅读了有关此主题的几篇文章,但仍在苦苦挣扎。

我在下面的代码中突出显示了几个问题。在外键(FareYear)和多对多字段(Parent)上帮助我会很棒,我什至还没有将其包含在图形请求中。在如何编写 Python 石墨烯代码和 Graphiql 请求方面获得帮助会很好。非常感谢大家

代码如下:

模型(摘录):

class Student(models.Model):
    first = models.CharField(max_length=64)
    last = models.CharField(max_length=64)
    email = models.EmailField()
    phone = models.CharField(max_length=64)
    year = models.ForeignKey(Year, on_delete=models.CASCADE, related_name="students", blank=True)
    fare = models.ForeignKey(Fare, on_delete=models.CASCADE, related_name="at_fare", blank=True)
    parents = models.ManyToManyField(Parent, related_name="children", blank=True)

Schema.py:

class StudentType(DjangoObjectType):
    class Meta:
        model = Student

//Student Type是必须的吗????

class FareType(DjangoObjectType):
    class Meta:
        model = Fare

class YearType(DjangoObjectType):
    class Meta:
        model = Year

class ParentType(DjangoObjectType):
    class Meta:
        model = Parent

输入对象类型:

class StudentInput(graphene.InputObjectType):
    #id = graphene.ID() // is this field necessary??
    first = graphene.String()
    last = graphene.String()
    email = graphene.String()
    phone = graphene.String()
    year = graphene.Field(YearInput)
    fare = graphene.Field(FareInput)
    parents = graphene.List(ParentInput)

class FareInput(graphene.InputObjectType):
    #id = graphene.ID()
    level = graphene.String()
    price = graphene.Int()
    currency = graphene.String()

class YearInput(graphene.InputObjectType):
    #id = graphene.ID()
    name = graphene.String()

class ParentInput(graphene.InputObjectType):
    id = graphene.ID()
    first = graphene.String()
    last = graphene.String()
    email = graphene.String()
    phone = graphene.String()
    is_primary_contact = graphene.Boolean()
    is_billing_contact = graphene.Boolean()
    address_line1 = graphene.String()
    address_line2 = graphene.String()
    postcode = graphene.String()
    city = graphene.String()
    country = graphene.String()

Mutation(到目前为止,我什至还没有设法包含 Parent 字段):

class CreateStudent(graphene.Mutation):
    ok = graphene.Boolean()
    student = graphene.Field(StudentType)

    class Arguments:
        student_data=StudentInput(required=True)
        year_data=YearInput(required=True)
        fare_data=FareInput(required=True)

    def mutate(self, info, student_data, year_data, fare_data):
        student_data.year = year_data
        student_data.fare = fare_data
        student = Student.objects.create(**student_data)
        return CreateStudent(ok=ok, student=student)

GraphIQL 突变:

mutation CreateStudent($studentData: StudentInput!, $yearData: YearInput!, $fareData: FareInput!) {
     createStudent(studentData: $studentData, yearData: $yearData, fareData: $fareData) {
student {
  id
  first
  last
  phone
  email
  year {
    id
    name
  }
  fare {
    id
    level
    price
    currency
      }
    }
  }
}

变量

{ "studentData": 
    {
      "first":"Jake",
      "last":"Blog",
      "phone":"+447917421894",
      "email":"jake@blog.com"
    },
  "yearData": {
  "name": "Test"
    },
  "fareData": {"level": "MatTest", "price": 160, "currency": "EUR"}
}

这是来自 Graphiql 的错误消息,但我怀疑可能还有其他问题。

{
  "errors": [
    {
      "message": "null value in column \"fare_id\" of relation \"tutor_student\" violates not-null constraint\nDETAIL:  Failing row contains (13, Jake, Blog, jake@blog.com, +447817421894, null, null).\n",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "createStudent"
      ]
    }
  ],
  "data": {
    "createStudent": null
  }
}

【问题讨论】:

    标签: django graphql


    【解决方案1】:

    您需要创建或获取年份和票价实例并将其传递给您的 Student.objects.create() 调用。

    def mutate(self, info, student_data, year_data, fare_data):
        student_data.year = Year.objects.create(**year_data)
        student_data.fare = Fare.objects.create(**fare_data)
        student = Student.objects.create(**student_data)
        return CreateStudent(ok=ok, student=student)
    

    如果您可能重复使用现有年份和票价,您可以使用get_or_create

        student_data.year, _ = Year.objects.get_or_create(**year_data)
        student_data.fare, _ = Fare.objects.get_or_create(**fare_data)
    

    【讨论】:

    • 希林特感谢您的回答。我已经实现,但后来我得到以下错误:{“错误”:[{“消息”:“关系\“tutor_student\”的列\“fare_id\”中的空值违反了非空约束\nDETAIL:失败的行包含(18, Jake, 博客, jake@blog.com, +447817421894, null, null)。\n", "locations": [ { "line": 2, "column": 6 } ], "path": [ "createStudent" ] } ], "data": { "createStudent": null } } 谢谢你的帮助
    • 那个错误说null value in column \"fare_id\" of relation \"tutor_student\" violates not-null constraint。这意味着您在创建学生时没有提供票价实例。
    猜你喜欢
    • 2019-08-24
    • 2020-04-24
    • 2018-08-24
    • 2017-07-28
    • 2019-04-10
    • 2018-01-02
    • 2016-02-07
    • 2018-08-22
    相关资源
    最近更新 更多