【问题标题】:graphene-django: Determine Object type when multiple GraphQL object types use the same django model in node querygraphene-django:当多个 GraphQL 对象类型在节点查询中使用相同的 django 模型时确定对象类型
【发布时间】:2022-07-10 21:06:39
【问题描述】:

在执行node(id: ...) {} 查询时,这是专门针对graphene-django只是graphene)。

假设使用graphene_django.DjangoObjectType 链接到 same django 模型的具有 2 个(或更多)不同 GraphQL 对象类型的固定架构:

import graphene_django
from .models import Org as OrgModel

class Org(graphene_django.DjangoObjectType):
    class Meta:
        model = OrgModel
        fields = (
            "id",
            "name",
            "billing"
        )

class AnonymousOrg(graphene_django.DjangoObjectType):
    class Meta:
        model = OrgModel
        fields = (
            "id",
            "name",
        )

假设对 ID 为 7eca71ed-ff04-4473-9fd1-0a587705f885Org 进行查询。

btoa('Org:7eca71ed-ff04-4473-9fd1-0a587705f885')
'T3JnOjdlY2E3MWVkLWZmMDQtNDQ3My05ZmQxLTBhNTg3NzA1Zjg4NQ=='
{
  node(id: "T3JnOjdlY2E3MWVkLWZmMDQtNDQ3My05ZmQxLTBhNTg3NzA1Zjg4NQ==") {
    id
    __typename
    ... on Org {
      id
    }
  }
}

返回:

{
  "data": {
    "node": {
      "id": "QW5vbnltb3VzT3JnOjdlY2E3MWVkLWZmMDQtNDQ3My05ZmQxLTBhNTg3NzA1Zjg4NQ==",
      "__typename": "AnonymousOrg"
    }
  }
}

它返回另一个对象类型 'AnonymousOrg:7eca71ed-ff04-4473-9fd1-0a587705f885',尽管中继 ID 指定它是一个 Org 对象。

graphene-django 中是否有办法“提示”或提供详细信息以确保返回类型是否在 ID 及其片段中指定?

问题说明

其他问题正在讨论graphene,而不是专门讨论graphene-django,它在这种情况下进行类型确定。

这与Django-graphene multiple types for the same model 不同,因为有人询问如何处理字段权限以及重新考虑架构结构的可能性(例如,在公共和私有 API 架构之间进行拆分)——这不是这个问题的选择。

信用:这是石墨烯 django 模型基于Django-graphene multiple types for the same model 问题中的模型。

附:我在这里在跟踪器上创建了一个错误问题:graphene-django#1291 命名为“DjangoObjectType 使用相同的 django 模型无法解析正确的中继对象”。据说这个问题在几年前就已经解决了,但是沟通线路被跨越了。

【问题讨论】:

    标签: django graphene-django


    【解决方案1】:

    这要归功于 2020 年 5 月 25 日 @Boolangery (GitHub) 的 workaround

    class FixRelayNodeResolutionMixin:
        @classmethod
        def get_node(cls, info, pk):
            instance = super(FixRelayNodeResolutionMixin, cls).get_node( info, pk)
            setattr(instance, "graphql_type", cls.__name__)
            return instance
    
        @classmethod
        def is_type_of(cls, root, info):
            if hasattr(root, "graphql_type"):
                return getattr(root, "graphql_type") == cls.__name__
            return super(FixRelayNodeResolutionMixin, cls).is_type_of(root, info)
    

    用法,这里是一个 django User 模型的示例,其中有两个 Django Graphene 对象指向它:PublicUserTypeUserType

    from graphene_django import DjangoObjectType
    
    
    class PublicUserType(FixRelayNodeResolutionMixin, DjangoObjectType):
        class Meta:
            model = User
            interfaces = (graphene.relay.Node,)
            fields = ['id', 'first_name', 'last_name']
    
    class UserType(FixRelayNodeResolutionMixin, DjangoObjectType):
        class Meta:
            model = User
            interfaces = (graphene.relay.Node,)
            fields = ['id', 'first_name', 'last_name', 'profile']
    

    【讨论】:

    • 2020 年 5 月 25 日,以上内容归功于 GitHub 上的 this post。目前我已将其制作成 wiki。
    猜你喜欢
    • 2021-04-15
    • 2021-09-24
    • 1970-01-01
    • 2011-07-22
    • 2018-09-13
    • 1970-01-01
    • 2017-09-20
    • 2011-07-10
    • 2019-10-15
    相关资源
    最近更新 更多