Why do we call super().get_queryset() in Django's get_queryset method?
I have a method in my Django project:
def get_queryset(self): queryset = super(OrderListView, self).get_queryset() return queryset.filter(initiator=self.request.user) I don’t understand why we use queryset = super(OrderListView, self).get_queryset() inside get_queryset.
What is the purpose of this line? What exactly does it do? Why do we call super() here? Why do we call the same method (get_queryset) inside itself? I've tried to understand it, but explanations so far haven't made it clear to me. I would appreciate a simple and satisfying answer.
Before you can return a filtered queryset, you need to have a queryset that can be filtered. So the first line fetches the queryset, by some way that's defined in a superclass. The second line then returns a filtered version of it.
def get_queryset(self):
# 1. Get the original queryset
queryset = super(OrderListView, self).get_queryset()
# 2. Filter the queryset
return queryset.filter(initiator=self.request.user)
There are a few reasons for this.
First of all, ListView
can construct a QuerySet
in two ways: by specifying a .model
attribute, or a .queryset
attribute. So if you would use self.queryset
, it would not work for ListView
s where you use the .model
approach like:
from django.views.generic import ListView
class MyListView(ListView):
model = MyModel
# 🖟 will ***not*** work
def get_queryset(self):
return self.queryset.filter(initiator=self.request.user)
Secondly, the .get_queryset()
of a MultipleObjectMixin
, which is the mixin that gives a ListView
the .get_queryset()
method, also orders the queryset if .ordering
is defined, or .get_ordering()
returns something different from None
.
You can also define your own mixins, for example with:
class ActiveItemsMixin:
def get_queryset(self):
return super().get_queryset().filter(active=True)
and mix it in a view with:
class MyListView(ActiveItemsMixin, ListView):
# …
Then super().get_queryset()
will thus return items that have active=True
, and so you thus can "chain" filter operations and thus define useful mixins.
Note: Since PEP-3135 [pep], you don't need to call
super(…)
with parameters if the first parameter is the class in which you define the method, and the second is the first parameter (usuallyself
) of the function.