问题描述
我正在尝试为两个具体的类提供一个唯一的接口,这些具体的类相似并从一个通用的抽象类继承。
我的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
(此处为MetadataScalar
或MetadataChoices
)时, graphql 找不到具体类的 node 并输出以下错误消息:
Expected value of type "Metadatanode" but got: MetadataScalar.
mutation {
createMetadata (input: {
stringFormat: "foo"
sequence: 12
name: "bar"
}) {
Metadata {
name
sequence
}
}
}
如何使它很好地工作,而不必在查询的第二部分中指定两种不同的结果类型(MetadataScalar
和MetadataChoices
变量)?
解决方法
您可以使用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)