views:

185

answers:

3

Hi!

I want to do something like this:

Entries.objects.values('date.year','date.month')

but this line is not valid. How can I list blog entries by year,month and display them in template?

Thanks!

+1  A: 

Here is some code snipped from my blog where I list all of the blog entries within a certain year:

Entries.objects.filter(draft=drafts).filter(posted_date__year=year).order_by(order_by)

In the above:

  • drafts is a boolean which specifies whether to show completed items or not.
  • year is the selected year
  • order_by is some ordering column name.

You should be able to easily modify this example to also include the month. The above shows that you can combine multiple filters in a row.

Brian R. Bondy
+5  A: 

If you set

entry_list = Entry.objects.order_by('pub_date')

in your view, you can display the months and years in the template using the ifchanged template tag.

{% for entry in entry_list %}
{% ifchanged %}<h3>{{entry.pub_date|date:"Y"}}</h3>{% endifchanged %}
{% ifchanged %}<h4>{{entry.pub_date|date:"F"}}</h4>{% endifchanged %}
<p>{{entry.title}}</p>
{% endfor %}


Another useful Django queryset method for blog archives is dates.

For example

entry_months = Entry.objects.dates('pub_date','month','DESC')

returns a DateQuerySet of datetime.datetime objects for each month that has Blog Entries. You can use this queryset in the template to create links to monthly archive pages.

Alasdair
+1  A: 

You can try with the built-in regroup tag.

In your view:

archives = Entries.objects.all()

In your template:

{% regroup archives by date.month as entries_by_month %}
{% for entries in entries_by_month %}
    <h1>{{ entries.list.0.date|date:"F Y" }}</h1>
    <ul>
    {% for entry in entries.list %}
        <li>{{ entry.title }}</li>
    {% endfor %}
    </ul>
{% endfor %}
kemar