class declaration: order of mixin and class name
If I change
class PostListMixin(PublishedPostsMixin, ListView)
to
class PostListMixin(PublishedPostsMixin, ListView)
it the overriden get_queryset won't work. Can someone explain why?
Answers
You might want to check out The History of Python: Method Resolution Order by Guido van Rossum. It's a little difficult to digest at first, give it a few reads.
from django.views.generic import ListView
from .models import Post
class PublishedPostsMixin(object):
def get_queryset(self):
queryset = super(PublishedPostsMixin, self).get_queryset()
return queryset.filter(published=True)
class GoodBlogListView(PublishedPostsMixin, ListView):
model = Post
class BadBlogListView(ListView, PublishedPostsMixin):
model = Post
In GoodBlogListView, get_queryset() is called first from the PublishedPostsMixin. The first line of PublishedPostsMixin.get_queryset() method calls super() to work it's way up the inheritance chain, aka call the parent's get_queryset() method. In this case that is ListView.get_queryset(). So queryset ends up being the result of ListView.get_queryset(). If you look on the fantastic ccbv.co.uk site, you can inspect ListView's get_queryset() method. Essentially what you will get back is self.model.objects.all(), self.model is the Post model.
Finally, your PublishedPostsMixin.get_queryset() method will return queryset.filter(published=True). Your mixin relies on ListView.get_queryset() to construct the original queryset of which it will then return a filtered version of.
If you reverse the order of inheritance as in BadBlogListView, the first get_queryset() to be run will be from ListView. If you inspect the get_queryset() method for list view you will notice that it does not call super(). Since that get_queryset() method is your first stop in the inheritance chain and it does not call super(), you simply get the result of ListView.get_queryset(). PublishedPostsMixin.get_queryset() is never called.
If you plan on using class-based views, understanding multiple inheritance is a necessity.
I don't see any differences here. Care to expound on this a little more?