有没有办法让石墨烯与 django GenericRelation 字段一起工作?

Is there a way to get graphene to work with django GenericRelation field?

我有一些 Django 模型通用关系字段,我希望它们出现在 graphql 查询中。石墨烯是否支持通用类型?

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 查询结果中。仅显示代理商和功能。

您需要向您的架构公开 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()

它并不完美,但我是这样做的: 首先创建一个代理 class(我发现 abstract = True 也可以),这应该具有所有可能的 Generalically Related 对象可以具有的所有字段。

class CatchAll(RelatedModelYouInheritFrom):
    class Meta:
        proxy = True

然后为代理模型做一个类型

class CatchAllType(DjangoObjectType):
    class Meta:
        model = CatchAll
        fields = ('some_var', 'other_var')

并且在 returns 多个 class 实例的解析器中:将实例转换为 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