Есть ли способ заставить графен работать с полем django GenericRelation?

У меня есть несколько общих полей отношения модели 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. Только агентство и особенности показывают.

2 ответа

Вам нужно разоблачить 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()

Это не идеально, но я сделал это так: сначала создайте прокси-класс (я обнаружил, что 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
Другие вопросы по тегам