@grecha10

DRF ManytoMany фильтрация по связанной модели, в подзапросе?

Есть две модели, модель Page и модель Banner, связанные ManyToMany.
Дергается API с параметрами, который возвращает список страниц и баннеров для каждой страницы. В модели Banner есть поле is_show по которому нужно дополнительно фильтровать список баннеров, т.е. в админке баннер может быть выбран для модели, но если is_show=False то в 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',
        verbose_name='Страницы, на которых требуется показывать баннер')


class Page(models.Model):
    name = models.CharField(verbose_name='Заголовок', 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__'


Вопрос, как сделать фильтрацию Banner по полю is_show?

Если просто переопределять queryset для вьюхи таким образом:
queryset = Page.objects.filters(banners__is_show=True)

то это не то поведение, которое требуется. Таким способом, я фильтрую список Page, а мне нужно "вклинится" в фильтрацию списка Banner.
  • Вопрос задан
  • 352 просмотра
Решения вопроса 1
@lukyoung
используй prefetch_related(Prefetch('banners_set', queryset=Banners.objects.all())) а в фильтрах создай метод by_is_show(...) для поля is_show в котором фильтруй banners_set по is_show
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы