0

I have a ListView (generic CBV) of events. This ListView should dynamically update each day, so that "old" events (i.e. events that have already happened) are excluded from the context when a user visits the page.

I just noticed that this page is not actually behaving as expected (a server restart is required in order for the ListView to update). I have a suspicion that this is because I'm using the queryset method, and that I should be doing the processing earlier:

class EventDirectoryView(ListView):
    model = Event
    # Exclude objects that are expired
    queryset = Event.objects.exclude(deadline__lt=(date.today()-timedelta(1)))
    template_name = 'event-directory.html'

In order to achieve my desired outcome, what is the earliest I should be modifying the queryset so that it is run each time the page is loaded?

rnevius
  • 26,578
  • 10
  • 58
  • 86

1 Answers1

1

You should override the get_queryset() method:

class EventDirectoryView(ListView):
    ...
    def get_queryset(self):
        return Event.objects.exclude(deadline__lt=(date.today()-timedelta(1)))
catavaran
  • 44,703
  • 8
  • 98
  • 85
  • Doesn't the `queryset` I have specified in my class get [passed to get_queryset()](https://docs.djangoproject.com/en/1.7/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_queryset)? – rnevius Feb 25 '15 at 09:36
  • Yes, by default `get_queryset()` returns the `queryset` attribute but you don't need the default behaviour. You need to create new queryset for each request instead of using the same queryset for all requests. That is why you have to override this method. – catavaran Feb 25 '15 at 09:48
  • Looking at [the source code](https://github.com/django/django/blob/master/django/views/generic/list.py#L26) helped clear this up. Essentially, `queryset` is defined once. If I use the default `get_queryset()` method, without overriding it, the original `queryset` value is used. This `queryset` value is determined the first time the view is requested, and it isn't "re-calculated" after that point. That's why `get_queryset()` needs to be overridden. Thanks for the help! – rnevius Feb 25 '15 at 09:59
  • Follow up: Is it redundant to have a `model` and `queryset` defined? It seems like the `model` is only used if there is no `queryset` defined. Is this correct? – rnevius Mar 02 '15 at 12:41
  • I am not sure but I think yes, you can omit the `model` in case of defined `queryset`. – catavaran Mar 02 '15 at 13:08