QuerySet Trouble in Django Class-based Views

So in a recent project I had a very strange publishing bug where two models out of more than a dozen or so, were tossing out 404s where a detail page should be. We had just instituted a lot of caching pieces to the project, which turned out to be red-herrings and probably had something to do with how long it took to track down this bug. But for the sake of the internet and anyone else who finds their model’s publish datetimes strangely cached despite their best efforts to get them to show up, here’s some good advice:

Don’t use the “queryset” model attribute for your view class, override the “get_queryset” function.

In code:

1
2
def AwesomeDetailView(DetailView):
    queryset = AwesomeModel.objects.all()

The above will save the result of the queryset in the view when your server process starts up. Probably not what you actually want.

The solution is to either:

1
2
def AwesomeDetailView(DetailView):
    queryset = AwesomeModel.objects.all

Note, the lack of () so we’re passing the function all instead of the resolved value of the function call.

Or override the get_queryset class function:

1
2
3
def AwesomeDetailView(DetailView):
    def get_queryset(self):
        return AwesomeModel.objects.all()

Either one will do, though I’m sure someone somewhere has a philosophical point to make for one over the other. For me, I’m just awfully glad to have a working website again.