当我执行一个变异(使用SerializerMutation)并返回创建的对象时,响应中包含一个声明为AssertionError的状态
User Error: expected iterable, but did not find one for field CreateTableMutationPayload.footSet
问题出在executor.py complete_list_value
中,该脚本检查footSet是否可迭代。实际上,它是一个RelatedManager,它本身不能迭代。通常,您只需执行table.foot_set.all()即可获得迭代。我发现确实可以在“查询”中正常运行,但不能在“突变”中运行。
我创建了a sample project来说明这一点。
我有一个非常简单的Table
模型,其中有几个Foot
。两个对象都通过Relay公开,效果很好。查询:
{ tables {
edges {
node {
id, name, height
footSet {
edges {
node {
id, number, style
} } } } } } } }
返回:
{
"data": {
"tables": {
"edges": [
{
"node": {
"id": "VGFibGVOb2RlOjE=",
"name": "test1",
"height": 11,
"footSet": {
"edges": [
{
"node": {
"id": "Rm9vdE5vZGU6MQ==",
"number": 1,
"style": "plain"
}
},
{
"node": {
"id": "Rm9vdE5vZGU6Mg==",
"number": 2,
"style": "Almost plain"
} } ] } } } ] } } }
但是是一个突变:
mutation {
createTable(input: {
name:"test3"
height: 60
footSet: [
{ number: 1, style: "Rococo" }
]
}) {
name
height
footSet {
id
number
style
}
}
}
收益:
{
"errors": [
{
"message": "User Error: expected iterable, but did not find one for field CreateTableMutationPayload.footSet. (furniture.Foot.None)"
}
],
"data": {
"createTable": {
"name": "test3",
"height": 60,
"footSet": null
}
}
}
要使用示例,您只需要
source bin/activate
pip -r requirements.txt
./manage.py migrate
./manage.py createsuperuser
./manage.py runserver :7000
Connect to localhost:7000/admin
Go to localhost:7000/graphql
schema.py:
import json
import graphene
from graphene import Schema
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from furniture.models import Table, Foot
from graphene_django.rest_framework.mutation import SerializerMutation
from furniture.serializers import TableSerializer
class TableNode(DjangoObjectType):
class Meta:
model = Table
filter_fields = "__all__"
interfaces = (graphene.relay.Node,)
class FootNode(DjangoObjectType):
class Meta:
model = Foot
filter_fields = "__all__"
interfaces = (graphene.relay.Node,)
class Query(graphene.ObjectType):
tables = DjangoFilterConnectionField(TableNode)
class CreateTableMutation(SerializerMutation):
class Meta:
serializer_class = TableSerializer
model_operations = ['create', 'update']
lookup_field = 'id'
class Mutation(graphene.ObjectType):
create_table = CreateTableMutation.Field()
schema = Schema(query=Query, mutation=Mutation)
和serializers.py:
from rest_framework import serializers
from .models import Table, Foot
class FootSerializer(serializers.Serializer):
class Meta:
model = Foot
number = serializers.IntegerField()
style = serializers.CharField()
def update(self, instance, validated_data):
pass
def create(self, validated_data):
pass
def get_attribute(self, instance):
print("get_attr", self, instance)
return []
class TableSerializer(serializers.Serializer):
class Meta:
model = Table
name = serializers.CharField()
height = serializers.IntegerField()
foot_set = FootSerializer(many=True, required=False)
def update(self, instance, validated_data):
pass
def create(self, validated_data):
feet = validated_data.pop('foot_set') if 'foot_set' in validated_data else []
print("feet", type(feet), str(feet))
table = Table.objects.create(name=validated_data['name'], height=validated_data['height'])
for foot in feet:
Foot.objects.create(table=table, number=foot['number'], style=foot['style'])
table.refresh_from_db()
print("created table", table)
return table
# also tried Table.objects.filter(id=table.id).prefetch_related("foot_set").first()
如何将我的模型及其潜在的子对象退还给石墨烯,以便根据突变的要求进行处理?我做错了吗?有人有这样的例子可行吗?