在子查询中对相关模型进行 DRF ManytoMany 过滤?

DRF ManytoMany filtering on related model, in subquery?

有两个模型,Page模型和Banner模型,多对多关联。 参数 API 被抽动,其中 return 是页面列表和每个页面的横幅。横幅模型有一个字段 is_show,您需要通过该字段额外过滤横幅列表,即在管理面板中,可以为模型选择横幅,但是如果 is_show = False,那么您不需要return它到API.

观看次数

class PagesListView(generics.ListAPIView,
                   viewsets.GenericViewSet):
    queryset = Page.objects.all()
    serializer_class = PageSerializer

型号

class Banner(models.Model):
    title = models.CharField(verbose_name='Заголовок', max_length=255, null=True, blank=True)
    is_show = models.BooleanField(verbose_name='Управление отображением', null=False)
    pages = models.ManyToManyField(
        Page, blank=True, related_name='banners')

class Page(models.Model):
    name = models.CharField(max_length=255, null=True, blank=True)

序列化器

class BannerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Banner
        fields = '__all__'


class PageSerializer(serializers.ModelSerializer):
     banners = BannerSerializer(read_only=True, many=True)

     class Meta:
        model = Page
        fields = '__all__'

问题是如何按is_show字段过滤Banner?

如果您只是像这样重写视图的查询集:

queryset = Page.objects.filters(banners__is_show=True)

那么这不是我们想要的行为。这样,我在过滤Page列表,我需要“楔入”过滤Banner列表。

您可以使用 related_nameprefetch_related

来完成

例如:

queryset = Page.objects.all().prefetch_related(
        Prefetch('banners', queryset=Banner.objects.filter(is_show=True)))