到目前为止,我可以在不需要 DjangoObjectType
的情况下使用 Graphene。我尽量避免它,因为我不打算离我的 Django 模型类太近。但是我在使用 Graphene 实现 Relay 时遇到了问题:
class HouseholdNode(graphene.ObjectType):
class Meta:
interfaces = (graphene.relay.Node,)
name = graphene.String()
@classmethod
def get_node(cls, info, id):
return Household.objects.get(pk=id)
失败并出现以下错误:
Abstract type Node must resolve to an Object type at runtime for field Query.node with value "Test", received "None".
“测试”直接来自 Household
的 __str__
函数。
下次尝试:
@classmethod
def get_node(cls, info, id):
return cls(Household.objects.get(pk=id))
cls
是 HouseholdNode
。然而,这会产生错误的结果:
"node": {
"id": "SG91c2Vob2xkOlRlc3Q=",
"name": null
}
ID其实是“Test”。
有效的解决方案:
@classmethod
def get_node(cls, info, id):
household = Household.objects.get(pk=id)
return cls(name=household.name)
但是我非常怀疑这就是 Graphite 烯能为我做的全部。我真的必须将真实数据对象包装到 HouseholdNode
中吗?我已经有了 resolve 函数,难道不能简单地使用这些函数吗?
这些方面的文档非常缺乏,请赐教。
最佳答案
抽象类型(如 graphene.relay.node.Node
)由 executor 解析使用 graphql.execution.executor.complete_abstract_value
.
实际上,以Node
为接口(interface)的ObjectTypes 从graphene 向上传递到graphql 层,每个包装为GrapheneInterfaceType
。 . resolve_type
这些对象中的每一个(最终提供了错误的来源)调用 graphql.execution.executor.get_default_resolve_type_fn
.
此函数缩小了可以返回的可能类型的范围 (possible_types
),然后遍历这些类型,检查 is_type_of
属性是否可调用以及它是否返回 True。重要的是要注意 possible_types
是 Node
的用户定义子类,继承自 graphene.types.objecttype.ObjectType
具有 is_type_of = None
.因此,你得到了 GraphQLError
因为没有类型被解析。
解决方案是在您的对象类型上定义一个 is_type_of
方法(或者创建一个抽象的 ObjectType,您可以使用已经实现的子类)。例如,here is the code在 graphene-sqlalchemy
中实现了 is_type_of
逻辑,在 graphene-django
中,code is here .
@classmethod
def is_type_of(cls, root, info):
if isinstance(root, SimpleLazyObject):
root._setup()
root = root._wrapped
if isinstance(root, cls):
return True
if not is_valid_django_model(type(root)):
raise Exception((
'Received incompatible instance "{}".'
).format(root))
model = root._meta.model._meta.concrete_model
return model == cls._meta.model
关于python - Django 模型对象和 Graphene get_node,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48345189/