如何将相关序列化器中的嵌套查询集限制为相关模型实例的子集?

时间:2018-08-10 02:50:30

标签: django django-rest-framework

我有曲目和专辑。我希望能够将曲目标记为已删除,但不能将其从数据库中删除。我希望标记为已删除(is_deleted = True)的曲目不会显示在嵌套序列化程序的API中。

我在TrackSerializer.py上尝试了一个自定义的“ get_queryset”方法,但未调用。

serializers.py

class TrackSerializer(serializers.ModelSerializer):

    class Meta:
      model = Track

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True)
    ### How do I limit tracks in the related/nested serializer to tracks on this album that have not been deleted?

models.py

class Track(models.Model):
  name = models.CharField()
  is_deleted = models.BooleanField(default=False)
  album = models.ForeignKey(Album, related_name="tracks") 

class Album(models.Model):
  name = models.CharField()

3 个答案:

答案 0 :(得分:1)

我不知道您的看法如何。可以说您正在使用视图集。您可以覆盖def destroy()函数。在其中获取对象并更改is_deleted = True的状态
例如:

def destroy(self, request, *args, **kwargs):
    instance = self.get_object()
    instance.is_deleted = True
    instance.save()
    return Response(status=status.HTTP_204_NO_CONTENT)

对于第二个问题,我建议为Django使用filters.BaseFilterBackend

编写一个显式过滤器

例如:

import django_filters
from rest_framework import filters  

class TrackFilterBackend(filters.BaseFilterBackend):

        def filter_queryset(self, request, queryset, view):
            return queryset.filter(is_deleted=False)

然后将其作为filter_class = TrackFilterBackend添加到您的视图中。

您可以在DJango REST filtering

中找到更多详细信息

答案 1 :(得分:1)

您也可以使用SerializerMethodField

class AlbumSerializer(serializers.ModelSerializer):
    tracks = SerializerMethodField()

    def get_tracks(self, album):
        tracks = album.track_set.filter(is_deleted=False)
        return TrackSerializer(tracks, many=True).data

答案 2 :(得分:0)

我确定我需要创建自定义ListSerializer,因为我已经使用过many=True

这是我在serializers.py中得到的结果

class DeletedListSerializer(serializers.ListSerializer):

    def to_representation(self, data):
        iterable = data.exclude(is_deleted=True) if isinstance(data, models.Manager) else data
        return [
            self.child.to_representation(item) for item in iterable
        ]


class TrackSerializer(serializers.ModelSerializer):

    class Meta:
      model = Track

class AlbumSerializer(serializers.ModelSerializer):
    tracks = TrackSerializer(many=True)
    ### How do I limit tracks in the related/nested serializer to tracks on this album that have not been deleted?

    @classmethod
    def many_init(cls, *args, **kwargs):
        kwargs['child'] = cls()
        return DeletedListSerializer(*args, **kwargs)