提问人:Pavel Reznikov 提问时间:5/18/2017 最后编辑:sazzy4oPavel Reznikov 更新时间:9/14/2023 访问量:1249
嵌套对象的突变
Mutation for nested object
问:
我正在尝试为“复杂”对象实现 GraphQL 突变。假设我们有一个有三个字段: 和 ,它是具有一个字段的对象:Contact
firstName
lastName
address
street
这是我的python方案实现:
class Address(graphene.ObjectType):
street = graphene.String(description='Street Name')
class AddressInput(graphene.InputObjectType):
street = graphene.String(description='Street Name', required=True)
class Contact(graphene.ObjectType):
first_name = graphene.String(description='First Name')
last_name = graphene.String(description='Last Name')
address = graphene.Field(Address, description='Contact address')
class ContactInput(graphene.InputObjectType):
first_name = graphene.String(description='First Name', required=True)
last_name = graphene.String(description='Last Name', required=True)
address = AddressInput(description='Contact address', required=True)
class CreateContact(graphene.Mutation):
class Input:
contact = ContactInput()
contact = graphene.Field(Contact, description='Created Contact object')
@staticmethod
def mutate(instance, args, context, info):
contact = Contact(**args['contact'])
return CreateContact(contact=contact)
当我运行此查询时:
mutation CreateContact($contact: ContactInput!) {
createContact(contact: $contact) {
contact {
firstName
address {
street
}
}
}
}
具有以下变量:
{
"contact": {
"address": {
"street": "Bond Blvd"
},
"firstName": "John",
"lastName": "Doe"
}
}
我得到以下结果:
{
"createContact": {
"contact": {
"address": {
"street": null
},
"firstName": "John"
}
}
}
正如你所看到的,字段在结果中。street
null
如果我将方法更改为:mutate
@staticmethod
def mutate(instance, args, context, info):
args['contact']['address'] = Address(**args['contact']['address'])
contact = Contact(**args['contact'])
return CreateContact(contact=contact)
但我不确定这是否是正确的方法。
因此,请建议一种启动嵌套结构的正确方法。
答:
0赞
haguirrear
9/14/2023
#1
您使用的是哪个版本的石墨烯?看起来用于 Adress ObjectType 的默认 resovler 无法解析字典。
在石墨烯中,默认 https://docs.graphene-python.org/en/latest/types/objecttypes/#defaultresolver:
解析程序将查找与字段名称匹配的字典键。否则,解析程序将从与字段名称匹配的父值对象中获取属性
您可以尝试使用特定的解析程序配置 Address 类:
from graphene.types.resolver import dict_or_attr_resolver, dict_resolver
class Address(graphene.ObjectType):
street = graphene.String(description="Street Name")
class Meta:
default_resolver = dict_or_attr_resolver
另外,对于我来说,使用当前最新版本的石墨烯(3.3),以下内容工作正常:
class Address(graphene.ObjectType):
street = graphene.String(description="Street Name")
class AddressInput(graphene.InputObjectType):
street = graphene.String(description="Street Name", required=True)
class Contact(graphene.ObjectType):
first_name = graphene.String(description="First Name")
last_name = graphene.String(description="Last Name")
address = graphene.Field(Address, description="Contact address")
class ContactInput(graphene.InputObjectType):
first_name = graphene.String(description="First Name", required=True)
last_name = graphene.String(description="Last Name", required=True)
address = AddressInput(description="Contact address", required=True)
class CreateContact(graphene.Mutation):
class Input:
contact = ContactInput()
contact = graphene.Field(Contact, description="Created Contact object")
def mutate(root, info, **args):
contact = Contact(**args["contact"])
return CreateContact(contact=contact)
def test_resolver():
query = """
mutation CreateContact($contact: ContactInput!) {
createContact(contact: $contact) {
contact {
firstName
address {
street
}
}
}
}
"""
client = Client(schema)
response = client.execute(
query,
variables={
"contact": {
"address": {"street": "Bond Blvd"},
"firstName": "John",
"lastName": "Doe",
}
},
)
assert response == {
"data": {
"createContact": {
"contact": {
"address": {
"street": "Bond Blvd",
},
"firstName": "John",
}
}
}
}
评论