开发者

Listing blog entries by year,month

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!


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.


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 %}


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.


Ok, let's try to do heavy lifting in data structure, instead of templates.

Let's create a utility.

import itertools

def group_by_values(posts, key):
    groups = {}
    for k, g in itertools.groupby(posts, key):
        if groups.get(k) is not None:
           groups[k].extend(list(g))
        else:
            groups[k] = list(g)
    return groups

Let's use the utility here.

entries = Entry.objects.all().order_by('date')
yearly_entries = group_by_values(entries, key=lambda x: x.date.year)
monthly_yearly_entries = {}
for k, v in yearly_entries.items():
    monthly_yearly_entries[k] = group_by_values(v, key=lambda x: x.date.month)
return monthly_yearly_entries

The result is nice dictionary with years and months as keys like this:

monthly_yearly_entries = {2013: {9: [Entry1, Entry2], 10: [Entry4, Entry5]}}

which you can show nicely in templates

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜