views:

144

answers:

1

I am using Django's generic views to create a blog site. The templates I created, entry_archive_day, entry_archive_month, entry_archive, and entry_detail all work perfectly.

But entry_archive_year does not. Instead, it is simply a valid page with no content (not a 404 or other error. It looks like it sees no objects in **object_list**.

I know that archive uses a latest list instead of object_list, but that's not the case with archive_year, correct?

Thanks!

+4  A: 

To solve your problem:

If you set make_object_list=True when calling archive_year, then the list of objects for that year will be available as object_list.

As a quick example, if your url pattern looks like

url(r'^(?P<year>\d{4})/$', 'archive_year', info_dict, name="entry_archive_year")

where info_dict is a dictionary containing the queryset and date_field, change it to

url(r'^(?P<year>\d{4}/$', 'archive_year', dict(info_dict,make_object_list=True),
        name="entry_archive_year")

Explanation:

The generic view archive_year has an optional argument make_object_list. By default, it is set to false, and object_list is passed to the template as an empty list.

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, this list of objects will be made available to the template as object_list. (The name object_list may be different; see the docs for object_list in the "Template context" section below.) By default, this is False.

A reason for this is that you might not always want to display the entire object list in the entry_archive_year view. You may have hundreds of blog posts for that year, too many to display on one page.

Instead, archive_year adds date_list to the template context. This allows you to create links to the monthly archive pages of that year, for the months which have entries.

date_list: A list of datetime.date objects representing all months that have objects available in the given year, according to queryset, in ascending order.

There's more info in the Django docs.

As requested in the comment below, an example of how to use date_list:

To use date_list, your entry_archive_year template would contain something like this:

<ul>
  {% for month in date_list %}

    <li><a href="/blog/{{month|date:"Y"}}/{{month|date:"b"}}>
          {{month|date:"F"}}</a></li>
  {% endfor %}
</ul>

Note that I've hardcoded the url - in practice it would be better to use the url template tag. For an example of date_list being used in the wild, look at the Django Weblog 2009 Archive.

Alasdair
Perfect! Thank you for your prompt and articulated answer. I wasn't sure of how to pass the setting from urls.py, but found this example: http://github.com/garethr/django-train/blob/ed60ace848e39d2d007929b2316d090886887a57/src/train/urls.pyAs a follow-up, do you have a link to a good example using date_list?
Wraith
I've added an example showing how to change urls.py in case somebody else has the same problem in future, and written a little more about `date_list`.
Alasdair
Thank you again for the detailed post and follow-up.
Wraith
You're very welcome.
Alasdair