嵌套突变Django+GraphQL



我是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)

架构.py:

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

//学生类型是必要的吗????

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()

突变(到目前为止,我甚至还没有设法将父母字段包括在内(:

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 constraintnDETAIL:  Failing row contains (13, Jake, Blog, jake@blog.com, +447817421894, null, null).n",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"createStudent"
]
}
],
"data": {
"createStudent": null
}
}

您需要创建或获取年份和票价实例,并将其传递到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)

最新更新