如何将 django 摘要 class 与 graphene-django 一起使用?
How to use a django abstract class with graphene-django?
我正在尝试为两个相似且继承自公共抽象 class.
的具体 classes 提供一个独特的接口
我的 django 模型 classes:
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 mutation时,成功创建元数据具体class。 ;-)
问题是,当查询要求在结果中创建具体 Metadata
时(此处为 MetadataScalar
或 MetadataChoices
),graphql 找不到具体 class 的 node 并输出以下错误消息:
Expected value of type "MetadataNode" but got: MetadataScalar.
供您参考,这里有一个示例查询:
mutation {
createMetadata (input: {
stringFormat: "foo"
sequence: 12
name: "bar"
}) {
metadata {
name
sequence
}
}
}
如何让它很好地工作,而不必在查询的第二部分指定两种不同的结果类型(metadataScalar
和 metadataChoices
变量)?
您可以使用 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
}
}
}
}
试试
... on metadata{
name
sequence
}
与您的界面。
Union 不能有任何字段,因此如果使用 Union 与 Interfaces,则需要重复。
https://docs.graphene-python.org/en/latest/types/unions/
我正在尝试为两个相似且继承自公共抽象 class.
的具体 classes 提供一个独特的接口我的 django 模型 classes:
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 mutation时,成功创建元数据具体class。 ;-)
问题是,当查询要求在结果中创建具体 Metadata
时(此处为 MetadataScalar
或 MetadataChoices
),graphql 找不到具体 class 的 node 并输出以下错误消息:
Expected value of type "MetadataNode" but got: MetadataScalar.
供您参考,这里有一个示例查询:
mutation {
createMetadata (input: {
stringFormat: "foo"
sequence: 12
name: "bar"
}) {
metadata {
name
sequence
}
}
}
如何让它很好地工作,而不必在查询的第二部分指定两种不同的结果类型(metadataScalar
和 metadataChoices
变量)?
您可以使用 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
}
}
}
}
试试
... on metadata{
name
sequence
}
与您的界面。 Union 不能有任何字段,因此如果使用 Union 与 Interfaces,则需要重复。 https://docs.graphene-python.org/en/latest/types/unions/