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