如何在graphene-django中使用django抽象类?

问题描述

我正在尝试为两个具体的类提供一个唯一的接口,这些具体的类相似并从一个通用的抽象类继承。

我的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,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'),choices=','.join(input.get('choices'))
            )
        return CreateMetadata(Metadata=Metadata)

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

问题是,当查询在结果中询问创建的具体Metadata(此处为MetadataScalarMetadataChoices)时, graphql 找不到具体类的 node 输出以下错误消息:

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

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

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

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

解决方法

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

在你的情况下,那将是:

False

graphql查询如下所示:

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)