Archiwa miesięczne

W zasadzie archiwa miesięczne w Django robi się w sposób banalny, gdyż biblioteka Django zawiera tak zwane widoki generyczne, czyli standardowe. (Gdyby czytał ten wpis ktoś nie znający Django, wyjaśniam, że nazwa "widok" w tym frameworku jest nieco myląca i wbrew pozorom nie oznacza szablonu strony, lecz funkcję, która, biorąc pod uwagę otrzymane żądanie HTTP, decyduje jakie dane pobrać z bazy i jakie zmienne wysłać do szablonu; w innych rozwiązaniach funkcja taka zwana jest kontrolerem).
Otóż jednym z fantastycznych pomysłów twórców Django jest przygotowanie takich "widoków" na standardowe okazje. Na przykład istnieje "widok", który wysyła do szablonu strony wszystkie obiekty pobrane z danej klasy modelu, na przykład wszystkie wpisy w blogu. Istnieją też widoki, które można użyć do budowy archiwów. Z tym że jest to zrobione "piętrowo" Jest więc widok, który przygotowuje listę lat, w których były wpisy, następnie w każdym roku listę miesięcy i dopiero w trzecim kroku w każdym miesiącu listę wpisów. W praktyce często wygodniej jest mieć archiwa w postaci:
- listopad 2009
- grudzień 2009
- styczeń 2010
etc.

Okazuje się, że też można to zrobić bardzo prosto. Miesięczne archiwa robimy wykorzystując widok generyczny. Wystarczy w pliku konfiguracyjnym urls.py poinformować Django, że URL typu http://mojadomena.com/2009/jan/ będzie obdługiwany przez standardowe archiwum miesięczne Django:

(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month', news_info),

Oczywiście wyżej w tym pliku trzeba zdefiniować zmienną news_info na przykład tak:

news_info = {
             "queryset"   : News.objects.all().reverse(),
             "date_field" : "date",
             "template_name"   : "archive.html"
             }

Natomiast naszą listę miesięcy robimy tak:

from news.models import News
 
def globs(request):
     news_glob = News.objects.values('title','slug').order_by('date').reverse()[:10]
     promo = News.objects.filter(promoted=True).order_by('date').reverse()[:3]
     pol={
             1:u"styczeń",
             2:u"luty",
             3:u"marzec",
             4:u"kwiecień",
             5:u"maj",
             6:u"czerwiec",
             7:u"lipiec",
             8:u"sierpień",
             9:u"wrzesień",
             10:u"październik",
             11:u"listopad",
             12:u"grudzień"
             }
     ang={
             1:"jan",
             2:"feb",
             3:"mar",
             4:"apr",
             5:"may",
             6:"jun",
             7:"lul",
             8:"aug",
             9:"sep",
             10:"oct",
             11:"nov",
             12:"dec"
          }
 
 
     month_list = []
     for i in News.objects.values('date'):
         month={'year':i['date'].year,'month':i['date'].month, 'pol':pol[i['date'].month], 'ang':ang[i['date'].month]}
         if month not in month_list:
             month_list.append(month)
 
     return {'news_glob': news_glob, 'promo':promo, 'month_list':month_list}

Odpowiedzi

Przydatne

Przy generowaniu dołożyłbym zamiane 1 3 4 5 na 01 02 03 04 itd... przy formacie 4/2 daty może być inaczej problem

month_id = i['created'].month;
if (month_id < 10):
month_id = "0%s" % month_id

Pozdrawiam,
Mariusz