Как удалить некоторые элементы из набора 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()