I have below model in my django app.
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)
There is a field status which has three values:
class SegmentStatuses:
STOPPED = 'stopped'
ACTIVE = 'active'
ARCHIVE = 'archive'
choices = ((STOPPED, STOPPED), (ACTIVE, ACTIVE), (ARCHIVE, ARCHIVE))
I need to add a default filter on this model where it should not show any results with status = Archive
So whenever someone query this model it should not show any Archive results.
CodePudding user response:
You can have 2 managers for your model: one for all objects and one for excluded objects
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()
As you can in this image, I just have only one object in DB and it has 'archive' status, so when I used the 'object' manager I didn't see any objects in the result, but when I used the 'object_all' manager I saw 1 object in the result
If you don't want to have access to archived status at all, you can ignore the objects_all
manager.
CodePudding user response:
In the view you can do it using exclude()
:
views.py:
Segment.objects.exclude(status='archive')
Edit:
You can override the get_queryset
of manager.
An Example:
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()
It will exclude the fields which have status='archive'
, so you can now directly do it as:
views.py:
Segment.objects.all()