Есть ли способ заставить графен работать с полем 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