【问题标题】:How to use a django abstract class with graphene-django?如何将 django 抽象类与 graphene-django 一起使用?
【发布时间】:2020-12-30 00:57:30
【问题描述】:

我正在尝试为两个相似的具体类创建一个独特的接口,这些类继承自一个公共抽象类。

我的 django 模型类:

class Metadata(models.Model):
    name = models.CharField(max_length=255)
    sequence = models.PositiveSmallIntegerField()
    is_choices = False

    class Meta:
        abstract = True


class MetadataScalar(Metadata):
    string_format = models.CharField(max_length=255, blank=True, null=True)


class MetadataChoices(Metadata):
    is_choices = True
    choices = models.CharField(max_length=255, blank=True, null=True)

我的石墨烯-django api:

class MetadataNode(DjangoObjectType):
    class Meta:
        interfaces = (Node,)
        connection_class = Connection
        model = Metadata
        fields = '__all__'


class MetadataScalarNode(MetadataNode):
    class Meta:
        interfaces = (Node,)
        connection_class = Connection
        model = MetadataScalar
        fields = '__all__'


class MetadataChoicesNode(MetadataNode):
    class Meta:
        interfaces = (Node,)
        connection_class = Connection
        model = MetadataChoices
        fields = '__all__'


class CreateMetadata(ClientIDMutation):
    metadata = Field(MetadataNode)

    class Input:
        name = String(max_length=255, required=True)
        sequence = Int(required=True)
        string_format = String()
        choices = List(String)

    @classmethod
    def mutate_and_get_payload(cls, root, info, **input):
        if 'string_format' in input:
            metadata = MetadataScalar.objects.create(
                name=input.get('name'),
                sequence=input.get('sequence'),
                string_format=input.get('string_format')
            )
        elif 'choices' in input:
            metadata = MetadataChoices.objects.create(
                name=input.get('name'),
                sequence=input.get('sequence'),
                choices=','.join(input.get('choices'))
            )
        return CreateMetadata(metadata=metadata)

查询CreateMetadata对应的graphql突变时,元数据具体类创建成功。 ;-)

问题在于,当查询要求在结果中创建具体的Metadata(此处为MetadataScalarMetadataChoices)时,graphql 找不到节点 em> 用于具体类并输出以下错误消息:

Expected value of type "MetadataNode" but got: MetadataScalar.

供您参考,这里是一个示例查询:

mutation {
  createMetadata (input: {
    stringFormat: "foo"
    sequence: 12
    name: "bar"
  }) {
    metadata {
      name
      sequence
    }
  }
}

如何使它正常工作,而不必在查询的第二部分指定两种不同的结果类型(metadataScalarmetadataChoices 变量)?

【问题讨论】:

    标签: python django graphql graphene-python graphene-django


    【解决方案1】:

    您可以使用Union 以便能够指定多个不同的结果类。

    在你的情况下,应该是:

    class MetadataScalarNode(DjangoObjectType):
        class Meta:
            interfaces = (Node,)
            connection_class = Connection
            model = MetadataScalar
            fields = '__all__'
    
    
    class MetadataChoicesNode(DjangoObjectType):
        class Meta:
            interfaces = (Node,)
            connection_class = Connection
            model = MetadataChoices
            fields = '__all__'
    
    
    class MetadataNode(Union):
        class Meta:
            types = (MetadataScalarNode, MetadataChoicesNode)
    

    graphql 查询将如下所示:

    mutation {
      createMetadata (input: {
        stringFormat: "foo"
        sequence: 12
        name: "bar"
      }) {
        metadata {
          __typename
          ... on MetadataScalarNode {
            name
            sequence
            stringFormat
          }
          ... on MetadataChoicesNode {
            name
            sequence
            choices
          }
        }
      }
    }
    
    

    【讨论】:

      【解决方案2】:

      试试吧

      ... on metadata{
        name
        sequence
      }
      

      与您的界面。 Union 不能有任何字段,因此如果使用 Union vs Interfaces,则需要有重复项。 https://docs.graphene-python.org/en/latest/types/unions/

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2011-02-11
      • 2021-01-09
      • 2020-10-06
      • 1970-01-01
      • 2011-03-07
      • 2016-12-25
      • 2011-09-19
      • 2019-09-04
      • 2019-11-13
      相关资源
      最近更新 更多