October 11, 2010

Recent months list in django

After a while I'm back with hot new stuff for you and me :) Recently I needed to select blog entries from 5 consecutive months (counting from current) to my footer archive list. The biggest problem was with the range of months in different years. After a lot of struggle I've came across a python module (probably you will have it in your default setup) `dateutil`, which gives new functionality to date related functions. Ok, so let's get to the code. My function was added to context processors to provide me functionality across whole site. Then we build a date object from current date. Next step is to run a generator expression (which I will speak about some more in the future as they're one of the most important features of python language together with coroutines and generator functions) for a increasing range of months (you can also use a list comprehension here if you need some additional lists functionality or a generator function. but I've tried to keep it simple). This gives us a generator object so we create a dictionary of it, with years as keys and corresponding months as dates. Because this dictionary provides us with numbers only, I've added additional function to translate them to string months values (note the brilliant Python's switch-case funcionality) here shown with Polish dictionary.

from datetime import datetime
from dateutil.relativedelta import relativedelta

def get_blog_archive(request):
    now = datetime.today()
    first_month = datetime(now.year, now.month, 1)
    previous_months = (first_month - relativedelta(months = months) for months in range(0, 5, 1))
    
    news_archive = {}
    for pm in previous_months:
        m = translate_month(pm.month)
        if news_archive.has_key(pm.year):
            news_archive[pm.year].append(m)
        else:
            news_archive[pm.year] = [m]
    m = translate_month(current_month)
    news_archive[current_year].append(m)
    
    return {'NEWS_ARCHIVE': news_archive,}

def translate_month(month):
    ret_month = ""
    months = {
            1: "Styczeń",
            2: "Luty",
            3: "Marzec",
            4: "Kwiecień",
            5: "Maj",
            6: "Czerwiec",
            7: "Lipiec",
            8: "Sierpień",
            9: "Wrzesień",
            10: "Październik",
            11: "Listopad",
            12: "Grudzień",
        }
    ret_month = months.get(month)
    return ret_month

Okay this code is nice but not really functional, beacuse we get months names as String (here with utf-8 chars) and its troublesome to parse them as urls. So here's a bit more functional approach :

    news_archive = []
    for pm in previous_months:
        d = datetime(pm.year,pm.month,1)
        news_archive.append(d)
    
    return {'NEWS_ARCHIVE': news_archive,}

And now in our template we just parse with for loop through list elements.
So that's all and stay tooned for some more advanced django examples. I'm doing a really big project right now but there's a ready shoutbox for django example, few implementations of django-registration, something about handling files and more :)

No comments:

Post a Comment