有没有办法让石墨烯与 django GenericRelation 字段一起工作?
Posted
技术标签:
【中文标题】有没有办法让石墨烯与 django GenericRelation 字段一起工作?【英文标题】:Is there a way to get graphene to work with django GenericRelation field? 【发布时间】:2019-10-02 10:58:54 【问题描述】:我有一些想要出现在 graphql 查询中的 django 模型通用关系字段。石墨烯是否支持泛型类型?
class Attachment(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
file = models.FileField(upload_to=user_directory_path)
class Aparto(models.Model):
agency = models.CharField(max_length=100, default='Default')
features = models.TextField()
attachments = GenericRelation(Attachment)
石墨烯类:
class ApartoType(DjangoObjectType):
class Meta:
model = Aparto
class Query(graphene.ObjectType):
all = graphene.List(ApartoType)
def resolve_all(self, info, **kwargs):
return Aparto.objects.all()
schema = graphene.Schema(query=Query)
我希望附件字段出现在 graphql 查询结果中。仅显示代理机构和功能。
【问题讨论】:
你应该包括你正在使用的石墨烯类。 【参考方案1】:您需要将Attachment
公开给您的架构。石墨烯需要type
才能用于任何相关领域,因此它们也需要公开。
此外,您可能想要解析相关的attachments
,因此您需要为它们添加解析器。
在你的石墨烯类中,尝试:
class AttachmentType(DjangoObjectType):
class Meta:
model = Attachment
class ApartoType(DjangoObjectType):
class Meta:
model = Aparto
attachments = graphene.List(AttachmentType)
def resolve_attachments(root, info):
return root.attachments.all()
【讨论】:
这不是我要找的答案。你如何从Attachment
类中公开content_object
?假设不同的相关对象具有不同的字段。如何根据返回的相关对象的类动态改变ObjectType?【参考方案2】:
这并不完美,但我是这样做的:
首先创建一个代理类(我发现abstract = True
也可以),它应该具有所有可能的通用相关对象可以具有的所有字段。
class CatchAll(RelatedModelYouInheritFrom):
class Meta:
proxy = True
然后为代理模型创建一个类型
class CatchAllType(DjangoObjectType):
class Meta:
model = CatchAll
fields = ('some_var', 'other_var')
在返回多个类实例的解析器中:将实例转换为 CatchAll:
class ModelWithGenericForeignKeyType(DjangoObjectType):
class Meta:
model = ModelWithGenericForeignKey
fields = ('other_var', 'some_var')
generic_relation = graphene.Field(CatchAllType)
def resolve_generic_relation(self, info, **kwargs):
d = self.generic_relation.__dict__ # turn the model in a dict
d.pop('_state') # remove the state
return CatchAll(**d) # cast the object of any class into the CatchAll
【讨论】:
以上是关于有没有办法让石墨烯与 django GenericRelation 字段一起工作?的主要内容,如果未能解决你的问题,请参考以下文章