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 ListViews 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 (usually self) of the function.

Вернуться на верх