Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django class-based views YearArchiveView

I'm trying out Django's class-based views, and liking them so far, but I can't get the YearArchiveView to give me anything. Here's my class:

class ThoughtsByYearView(YearArchiveView):
    template_name = "thoughts/index_by_year.html"
    queryset = Thought.objects.published()
    date_field = 'pub_date'
    context_object_name = 'thought_list'

and my urls.py:

urlpatterns = patterns('thoughts.views',
    url(r'^$', ThoughtsIndexView.as_view(), name='thoughts'),
    url(r'^(?P<year>\d{4})/$', ThoughtsByYearView.as_view(), name='thoughts_year'),
)

both thought_list and object_list return as empty lists. Redefining get_queryset doesn't result in anything either. ThoughtsIndexView returns the correct objects, so I'm sure it's just a dumb mistake I'm making. Can anyone tell me what it is?

Oh, and here's the test case that fails: (edit: the result in a browser is the same. None return)

def test_thoughts_by_year_has_thoughts(self):
    response = self.client.get(reverse('thoughts_year', args=[datetime.now().year]))
    thoughts_by_year = response.context_data['thought_list']
    self.assertGreater(len(thoughts_by_year), 0)
like image 945
Brian Hicks Avatar asked Jul 13 '26 09:07

Brian Hicks


2 Answers

It was a newbie mistake. I was not specifying make_object_list in the class. You can see how it's fixed at this commit.

From the documentation:

make_object_list

A boolean specifying whether to retrieve the full list of objects for this year and pass those to the template. If True, the list of objects will be made available to the context. By default, this is False.

So I'm not sure why that option exists, but it does. It doesn't make much sense to me to return nothing by default (maybe a pagination thing?)

like image 146
Brian Hicks Avatar answered Jul 15 '26 21:07

Brian Hicks


You've already solved the issue, but to answer your question about why that option exists, the documentation says:

A yearly archive page showing all available months in a given year.

... the template's context will be:

  • date_list: A DateQuerySet object containing all months that have objects available according to queryset, represented as datetime.datetime objects, in ascending order.

Class-based views are hard, and it's worth reading the documentation very carefully, diving into the source (mostly django.views.generic) and getting familiar with debugging techniques to step through the slightly tangled pile of inheritance going on with most views.

like image 41
supervacuo Avatar answered Jul 15 '26 22:07

supervacuo