Graphene-Django更新Mutation报错:String无法表示元组值
解决Graphene Mutation更新时字段变为元组的问题
你在编写Graphene更新Mutation时遇到了字段被设置为元组的错误,导致返回数据格式异常并报错。
问题代码
class UpdateAddress(graphene.Mutation): address = graphene.Field(AddressType) class Arguments: address_id = graphene.ID(required=True) index = graphene.String() street = graphene.String() house = graphene.String() flat = graphene.String() locality = graphene.Int() @classmethod def mutate(cls, root, info, address_id, index=None, street=None, house=None, flat=None, locality=None): address = Address.objects.get(pk=address_id) try: entry = Locality.objects.get(pk=locality) except Locality.DoesNotExist: entry = None address.index=index, address.street=street, address.house=house, address.flat=flat, address.locality=entry address.save() return UpdateAddress(address=address)
执行的更新查询
mutation { updateAddress( addressId: "1", index: "41204" street: "Shevchenko", house: "1", flat: "15", locality: 1 ) { address{ id, street, index, house, flat, locality{ id } } } }
报错信息
"errors": [ { "message": "String cannot represent value: ('41204',)", "locations": [ { "line": 12, "column": 7 } ], "path": [ "updateAddress", "address", "index" ] } ]
问题原因
你在给address对象的字段赋值时,每一行末尾都加了逗号,比如address.index=index,,这会让Python把赋值的右侧解析成一个单元素元组((index,)),而不是直接赋值index本身。所以最终数据库里的字符串字段被存储成了元组的字符串表示形式,导致Graphene无法正确序列化。
修正后的代码
只需要去掉赋值语句末尾的逗号即可:
class UpdateAddress(graphene.Mutation): address = graphene.Field(AddressType) class Arguments: address_id = graphene.ID(required=True) index = graphene.String() street = graphene.String() house = graphene.String() flat = graphene.String() locality = graphene.Int() @classmethod def mutate(cls, root, info, address_id, index=None, street=None, house=None, flat=None, locality=None): address = Address.objects.get(pk=address_id) try: entry = Locality.objects.get(pk=locality) except Locality.DoesNotExist: entry = None # 去掉每一行末尾的逗号 address.index = index address.street = street address.house = house address.flat = flat address.locality = entry address.save() return UpdateAddress(address=address)
额外优化建议
如果不想逐个字段赋值,可以用kwargs简化代码(注意过滤掉address_id和locality这些需要特殊处理的参数):
@classmethod def mutate(cls, root, info, address_id, locality=None, **kwargs): address = Address.objects.get(pk=address_id) if locality is not None: try: address.locality = Locality.objects.get(pk=locality) except Locality.DoesNotExist: pass # 批量更新其他字段 for field, value in kwargs.items(): if value is not None: setattr(address, field, value) address.save() return UpdateAddress(address=address)
内容的提问来源于stack exchange,提问作者AndyFlight
相关产品推荐
相关产品推荐

