python - Django 模型对象和 Graphene get_node

标签 python django graphql graphene-python

到目前为止,我可以在不需要 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))

clsHouseholdNode。然而,这会产生错误的结果:

"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_typesNode 的用户定义子类,继承自 graphene.types.objecttype.ObjectType 具有 is_type_of = None .因此,你得到了 GraphQLError因为没有类型被解析。

解决方案是在您的对象类型上定义一个 is_type_of 方法(或者创建一个抽象的 ObjectType,您可以使用已经实现的子类)。例如,here is the codegraphene-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/

相关文章:

python - "Matching"/Django中跨数据库的关系数据

graphql - 无法将大型 graphql 架构上传到 aws appsync

python - 如何检查用户输入的电话号码是否包含国家代码?

python - django中定义模型的顺序

python - 为什么在 Google App Engine 上使用 XHTML2PDF 时我的图像不显示?

django - 如何限制来自 GraphQL API 端点的匿名用户?

ios - 订阅失败错误 WSError(类型 : Starscream. ErrorType.upgradeError 消息 : \"Invalid HTTP upgrade\", 代码 : 400)?

python - 相当于 MATLAB 元胞数组的 Numpy

Python Pandas : Get index of multiple rows which column matches certain value

python - 将嵌套列表写入 CSV (Python)