在子查询中对相关模型进行 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_name
和 prefetch_related
来完成
例如:
queryset = Page.objects.all().prefetch_related(
Prefetch('banners', queryset=Banner.objects.filter(is_show=True)))
有两个模型,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_name
和 prefetch_related
例如:
queryset = Page.objects.all().prefetch_related(
Prefetch('banners', queryset=Banner.objects.filter(is_show=True)))