Как удалить некоторые элементы из набора queryset в зависимости от @property?

Я не знаю, как удалить результаты из набора запросов без использования .exclude(). Я хочу отфильтровать результат, если аргумент is_active передан в качестве параметра моего поиска на основе результата свойства is_active.

Моя модель с вычисляемым свойством 'is_active':

class Discount(models.Model):
    name = models.CharField(_("name"), max_length=255)
    date_start = models.DateField(_("Date start"), null=True, blank=True)
    date_end = models.DateField(_("Date end"), null=True, blank=True)
    [...]

    @property
    def is_active(self):
        if self.date_start and self.date_end:
            return self.date_start <= date.today() <= self.date_end
        return True

Мой набор представлений:

class DiscountViewSet(viewsets.ModelViewSet):    
    """
    A simple ViewSet for listing or retrieving discounts.
    """
    permission_classes = [CustomDjangoModelPermission]
    filter_backends = [DjangoFilterBackend]
    filter_fields = '__all__'
    
    def get_serializer_class(self):
        if hasattr(self, 'action') and self.action in ['list', 'retrieve']:
            return DiscountListSerializer
        return DiscountSerializer 
    
    def get_queryset(self):
        if self.request.user.is_staff:
            return Discount.objects.all().prefetch_related('products') \
                    .prefetch_related('machines').prefetch_related('categories')
        else:
            return Discount.objects.all().prefetch_related('products') \
                    .filter(machines__site__client__in=self.request.user.profil.client.all()) \
                    .prefetch_related('machines').prefetch_related('categories')
                    
    @swagger_auto_schema(manual_parameters=[height, width], 
                        responses={200: DiscountListSerializer})
    def list(self, request):
        height = self.request.query_params.get('height')
        width = self.request.query_params.get('width')
        queryset = self.get_queryset()
        queryset = self.filter_queryset(self.get_queryset())

        active_filter = request.data.get('is_active')

        if active_filter:
            for item in qs:
                if not item.is_active:
                    ???? // remove item
        
        if height and width:
            for discount in queryset:
                if discount.menu_photo:
                    discount.menu_photo = generate_thumbnail(discount.menu_photo, width, height)
                if discount.standby_photo:
                    discount.standby_photo = generate_thumbnail(discount.standby_photo, width, height)
        
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

В разделе списка, как я могу удалить в моем наборе запросов скидку, которая не активна? Я не могу использовать .exclude(), потому что is_active не зарегистрирован в базе данных.

Вы не можете фильтровать на методах модели. Вы можете написать пользовательский менеджер для модели, который фильтрует данные напрямую или возвращает аннотированный кверисет с фильтруемыми значениями, используя метод вашей модели

проверьте документацию для managers

class MyManager(models.Manager):
    def is_active(self):
        # Put your method here to filter the queryset
        return 

добавьте objects = MyManager() к модели (чтобы переопределить менеджер по умолчанию

)

тогда вы можете использовать MyModel.objects.is_active()

Вернуться на верх