class StudentModelManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return (
super(StudentModelManager, self)
.get_queryset()
.filter(is_deleted=False)
)
class StudentDetails(models.Model):
name = models.TextField(null=True, default=None)
is_deleted = models.BooleanField(default=False)
objects = StudentModelManager()
I have four entries in database 2 with is_deleted=False
and 2 with is_deleted=True
.
Because of StudentModelManager
in StudentDetails
model I could not retrieve records from database for is_deleted=True
.
I want to make sure that the default parameter while retrieving should be is_deleted=False
, but when explicit parameter is given like
is_deleted=True
, it should return objects with that value.
Actual Entries in db without applying StudentModelManager
to StudentDetails
model are :
>>> StudentDetails.objects.all()
<QuerySet [<StudentDetails: StudentDetails object (27)>, <StudentDetails StudentDetails object (29)>, <StudentDetails: StudentDetails object (30)>, <StudentDetails: StudentDetails object (28)>]>
Entries retrieved from db with applying StudentModelManager
to StudentDetails
model with is_deleted=False
:
>>> StudentDetails.objects.all()
<QuerySet [<StudentDetails: StudentDetails object (27)>, <StudentDetails StudentDetails object (29)>]>
Now see the actual issues, Not able to retrieve entries with is_deleted=True
>>> StudentDetails.objects.filter(is_deleted=True)
<QuerySet []>
Expected output is:
>>> StudentDetails.objects.filter(is_deleted=True)
<QuerySet [<StudentDetails: StudentDetails object (28)>, <StudentDetails StudentDetails object (30)>]>
How can this achieved?
Based on your requirements, it would be better to create a different manager to return StudentDetails which is deleted. If you change the default manager, the query for deleted objects would be impossible as the base QuerySet is filtered.
The use of different managers is suggested by Django documentation. ("You can attach as many Manager() instances to a model as you’d like. This is a non-repetitive way to define common “filters” for your models.").
With that in mind, you could use the following:
class StudentModelManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return (
super(StudentModelManager, self)
.get_queryset()
.filter(is_deleted=False)
)
class StudentDetails(models.Model):
name = models.TextField(null=True, default=None)
is_deleted = models.BooleanField(default=False)
objects = models.Manager()
existing_objects = StudentModelManager()
In the case of getting existing objects, you can use
StudentDetails.existing_objects.all()
In the case of query deleted objects, you can use
StudentDetails.objects.filter(is_deleted=True)
.