Django Year / Month Records Archive

I am new to Django and started the application, I made models, views, templates, but I want to add some kind of archive to the bottom of the page, something like http://www.flickr.com/photos/ionutgabriel/3990015411/ .

Therefore, I want to list all the years and next to them all the months from that year. Months that have posts to be links and not. I also want to translate the names of the months, because I need them in Romanian.

What i have done so far:

in my opinion:

def archive(request): arch = Post.objects.dates('date', 'month', order='DESC') archives = {} for i in arch: tp = i.timetuple() year = tp[0] month = tp[1] if year not in archives: archives[year] = [] archives[year].append(month) else: if month not in archives[year]: archives[year].append(month) return render_to_response('blog/arhiva.html', {'archives':archives}) 

and in my template:

  {% for years, months in archives.items %} {{ years }} {% for month in months %} <a href="{{ years }}/{{ month }}">{{ month }}</a> {% endfor %} <br /> {% endfor %} 

this returns something like:

  2008 10 2009 10 9 2007 10 

but I can’t sort them at all ... by years or by anything, and also I don’t know how to add all the months (names), I want them to be like this:

  2009 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2008 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2007 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 

with reference to months that have entries.

Thanks for the help!

ps sorry for my english

LE: Maybe I put the question wrong, I know how to get the dates, but I don’t know how to format them to look like this:

  2009 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2008 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2007 Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 

all I can get from arch = Post.objects.dates('date', 'month', order='DESC')

from

{{ archives }} in the template there is something like:

 [datetime.datetime(2009, 10, 1, 0, 0), datetime.datetime(2009, 9, 1, 0, 0), datetime.datetime(2008, 10, 1, 0, 0), datetime.datetime(2007, 10, 1, 0, 0)] 

then I tried the loop:

 {% for archive in archives %} {{ archive }} <br /> {% endfor %} 

and received:

 2009-10-01 00:00:00 2009-09-01 00:00:00 2008-10-01 00:00:00 2007-10-01 00:00:00 

After that I tried something like this:

 {% for archive in archives %} {{ archive|date:"Y: m" }} <br /> {% endfor %} 

and received:

 2009: 10 2009: 09 2008: 10 2007: 10 

Here I am stuck and do not know how to format the data, so I can get reporting years with all months and only months that have entries that will be links ...

Any ideas?

Thank you in advance!

+6
python django
source share
3 answers

Firstly, date and time format strings are provided in django docs . I think you need capital instead of the lowercase letter "M".

Since you want to display all 12 months of the year, even if only some of them have messages, we will create an archives object to go to the template. I decided to use a dictionary where

  • keys are years
  • the values ​​are a list of 12 [datetime, bool] pairs, where datetime is the month, and bool is True if there are records for that month.

Here we create the archives object in the view.

 from datetime import date def archive(request): arch = Post.objects.dates('date', 'month', order='DESC') archives = {} for i in arch: year = i.year month = i.month try: archives[year][month-1][1]=True except KeyError: # catch the KeyError, and set up list for that year archives[year]=[[date(y,m,1),False] for m in xrange(1,13)] archives[year][month-1][1]=True return render_to_response('blog/arhiva.html', {'archives':sorted(archives.items(),reverse=True)}) 

In the template, we repeat the months for each year and display a link, if necessary.

 {% for year, month_list in archives %} {{ year }} archives: {% for month, has_link in month_list %} {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %} {{ month|date:"M" }} {% if has_link %}</a>{% endif %} {% endfor %} {% endfor %} 

I have not checked all the code, so there may be some errors. It would be better to use the URL template tag for the link rather than the hardcoding url format. I feel that my answer may be overly complex, but I spent some time typing it, so I can share it with the world.


Internationalization

I have not used Django's internationalization features, so I cannot help with the translation. I recommend that you read the documentation and ask another question if you don’t understand a particular bit.

Having said that if you want to display months, it is only Romanian, here is an ugly way to do it.

First add the following line to the top of your archive function in the view.

 rom_months = ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sept', 'Oct', 'Noi', 'Dec'] 

Then substitute the following line in your view

 archives[year]=[[date(y,k+1,1),False,rom] for k, rom in enumerate(rom_months)] 

Finally replace in the template

following:
 ... {% for month, has_link, rom_month in month_list %} {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %} {{ rom_month }} ... 
+12
source share

Perhaps you should consider starting with a general view and building it.

+2
source share

Ok ... so the last code that works for me is:

in sight:

  rom_months = ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sept', 'Oct', 'Noi', 'Dec'] def arhiva(request): arch = Post.objects.dates('data', 'month', order='DESC') archives = {} for i in arch: year = i.year month = i.month try: archives[year][month-1][1] = True except KeyError: archives[year]=[[datetime.date(year,k+1,1),False,rom] for k, rom in enumerate(rom_months)] archives[year][month-1][1] = True return render_to_response('blog/arhiva.html', {'archives':sorted(archives.items(),reverse=True)}) 

and in the template:

 {% for year, month_list in archives %} {{ year }} Arhive: {% for month, has_link, rom_month in month_list %} {% if has_link %}<a href="/{{ month.year }}/{{ month.month }}/">{% endif %} {{ rom_month }} {% if has_link %}</a>{% endif %} {% endfor %} <br /> {% endfor %} 

and the result:

 2009 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2008 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2007 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 2003 Arhive: Ian Feb Mar Apr Mai Iun Iul Aug Sept Oct Noi Dec 

Thank you for help. You are the best! I'm n00b! :)

+2
source share

All Articles