当 class 多次涉及同一个通用关系时,如何序列化(使用 Django REST API)?

How can I serialize (with Django REST API) when class relates to the same generic relation multiple times?

我有一个 class,它多次引用相同的泛型 class 以获得不同的信息:

class Resort(models.Model):
    id = models.PositiveIntegerField(_('HapNr.'), primary_key=True)
    symbol = models.CharField(_('Kurzzeichen'), max_length=3, blank=True)
    short_description = GenericRelation('MultiLingualText',
                                   verbose_name=_('Beschreibung (ML)'),
                                   related_query_name='resortshortdescriptions')
    long_description = GenericRelation('MultiLingualText',
                                   verbose_name=_('Einleitung (ML)'),
                                   related_query_name='resortlongdescription')

class MultiLingualText(models.Model):
    language = models.ForeignKey(hmodels.LanguageCode, verbose_name=_('Sprache'))
    valid_from = models.DateField(_('Gültig ab'), default=timezone.now)
    text = models.TextField(_('Text'))
    content_type = models.ForeignKey(ContentType, verbose_name=_('Typ'))
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()
    atu_id = models.CharField(_('ATU Text Id'), max_length=12, editable=False, blank=True)
    atu_context = models.CharField(_('ATU Kontext'), max_length=1, editable=False, blank=True)

当我需要使用 Django Admin 处理这个 class 时,我有两个内联,每个内联都有一个查询集,为该关系选择正确的文本。这很好用。

我尝试通过为每个关系使用单独的序列化器和视图集来做类似的事情,但是当我检索一个度假村时,它仍然显示每个关系的所有文本。

class ResortSerializer(serializers.HyperlinkedModelSerializer):
    short_description = MultiLingualTextSerializerRSD(many=True, read_only=True)
    long_description = MultiLingualTextSerializerRLD(many=True, read_only=True)

    class Meta:
        model = Resort

class MultiLingualTextSerializerRSD(serializers.HyperlinkedModelSerializer):
    language = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
       model = MultiLingualText

class MultiLingualTextViewSetRSD(viewsets.ModelViewSet):
    serializer_class = MultiLingualTextSerializerRSD
    queryset = MultiLingualText.objects.exclude(atu_id='').order_by('resort', 'content_type', 'object_id',
                                                                '-valid_from')

class ResortViewSet(viewsets.ModelViewSet):
    queryset = Resort.objects.all().order_by('id')
    serializer_class = ResortSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('id', 'sihot_nr')

基本上我的问题是,如何为每组文本使用不同的查询集?或者这完全可能吗?

正确实施(感谢@lucasnadalutti)

class ResortSerializer(serializers.HyperlinkedModelSerializer):
    short_description = serializers.SerializerMethodField()
    long_description = serializers.SerializerMethodField()

    def get_short_description(self, obj):
        qs = MultiLingualText.objects.exclude(atu_id='').order_by('-valid_from', 'language__code')
        return MultiLingualTextSerializer(qs, many=True, read_only=True).data

    def get_long_description(self, obj):
        qs = MultiLingualText.objects.filter(atu_id='').order_by('-valid_from', 'language__code')
        return MultiLingualTextSerializer(qs, many=True, read_only=True).data

MultiLingualTextViewSetRSD 在这种情况下没有多大意义,因为你想要的是只在一个请求中发送度假村 他们的描述,因为它应该是.在普通的 ForeignKey 模型字段关系中,我很确定 ResortSerializer 会像您预期的那样仅序列化其相关记录,但我不确定 DRF 序列化程序如何处理泛型关​​系。

也就是说,一种解决方案是替换:

short_description = MultiLingualTextSerializerRSD(many=True, read_only=True)
long_description = MultiLingualTextSerializerRLD(many=True, read_only=True)

与:

short_description = SerializerMethodField()
long_description = SerializerMethodField()

并在 get_short_descriptionget_long_description 方法中实现过滤和序列化。另一种解决方案是删除这两个属性并将此逻辑放在序列化程序的 to_representation 方法中。