Как создать фильтр по умолчанию в наборе запросов django
У меня есть следующая модель в моем приложении django.
class Segment(BaseSegmentModel):
payload_json = JSONField(null=True, default=None, blank=True)
owner = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.SET_NULL, related_name='segments')
name = models.CharField(max_length=100, null=True, blank=False)
status = models.CharField(max_length=100, null=True, blank=True, choices=SegmentStatuses.choices, default=SegmentStatuses.STOPPED)
created_date = models.DateTimeField(null=True, auto_now_add=True)as
Существует поле status, которое имеет три значения,
Active
Running
Archive
Мне нужно добавить фильтр по умолчанию на эту модель, где она не должна показывать результаты со статусом = Архив.
Поэтому всякий раз, когда кто-то запрашивает эту модель, она не должна показывать никаких архивных результатов.
В представлении вы можете сделать это с помощью exclude()
:
views.py:
Segment.objects.exclude(status='archive')
Редактирование:
Вы можете переопределить get_queryset
менеджера.
Пример:
models.py
class AnyManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset()
return qs.exclude(status='archive')
class Segment(BaseSegmentModel):
payload_json = JSONField(null=True, default=None, blank=True)
owner = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.SET_NULL, related_name='segments')
name = models.CharField(max_length=100, null=True, blank=False)
status = models.CharField(max_length=100, null=True, blank=True, choices=SegmentStatuses.choices, default=SegmentStatuses.STOPPED)
created_date = models.DateTimeField(null=True, auto_now_add=True)
objects = AnyManager()
Это исключит поля, которые имеют status='archive'
, так что теперь вы можете сделать это напрямую как:
views.py:
Segment.objects.all()
Вы можете иметь 2 менеджера для вашей модели: один для всех объектов и один для исключенных объектов
class SegmentStatuses:
STOPPED = 'stopped'
ACTIVE = 'active'
ARCHIVE = 'archive'
choices = ((STOPPED, STOPPED), (ACTIVE, ACTIVE), (ARCHIVE, ARCHIVE))
class UnArchivedManager(models.Manager):
def get_queryset(self):
return super(UnArchivedManager, self).get_queryset().exclude(status=SegmentStatuses.ARCHIVE)
class Segment(BaseSegmentModel):
payload_json = JSONField(null=True, default=None, blank=True)
owner = models.ForeignKey(CustomUser, null=True, blank=True, on_delete=models.SET_NULL, related_name='segments')
name = models.CharField(max_length=100, null=True, blank=False)
status = models.CharField(max_length=100, null=True, blank=True, choices=SegmentStatuses.choices, default=SegmentStatuses.STOPPED)
created_date = models.DateTimeField(null=True, auto_now_add=True)
objects = UnArchivedManager()
objects_all = models.Manager()
Как вы можете видеть на этом изображении, у меня только один объект в DB и он имеет статус 'archive', поэтому когда я использовал менеджер 'object', я не увидел ни одного объекта в результате, но когда я использовал менеджер 'object_all', я увидел 1 объект в результате
Если вы вообще не хотите иметь доступ к архивному состоянию, вы можете игнорировать менеджер objects_all
.