from django.template import Library, Node from django.db.models import get_model from django.db.models import Q from datetime import datetime register = Library() class ArchiveDatesNode(Node): def __init__(self, model, fieldnames, kind, varname): self.kind, self.varname = kind, varname self.fieldnames = fieldnames.split('|') self.model = get_model(*model.split('.')) def render(self, context): now = datetime.now() fieldnames = self.fieldnames[:] # do an OR lookup with the given fieldnames query = Q(**{'%s__lte' % fieldnames.pop(0): now}) for fieldname in fieldnames: query = query | Q(**{'%s__lte' % fieldname: now}) try: context[self.varname] = self.model._default_manager.filter(query).dates(self.fieldnames[0], self.kind, order='DESC').distinct() except self.model.DoesNotExist: pass return'' def get_archive_dates(parser, token): """ {% get_archive_dates app.Model fieldname as variablename %} {% get_archive_dates news.Entry pub_date as archive_dates %} {% get_archive_dates news.Entry pub_date year as archive_dates %} {% get_archive_dates events.Event start_date|end_date year as archive_dates %} """ bits = token.contents.split() if len(bits) < 5: raise template.TemplateSyntaxError, "'%s' tag takes at least three arguments" % bits[0] elif len(bits) > 6: raise template.TemplateSyntaxError, "'%s' tag takes at most four arguments" % bits[0] if bits[3] == 'as': kind = 'month' varname = bits[4] elif bits[4] == 'as': kind = bits[3] varname = bits[5] else: raise TemplateSyntaxError, "Second last argument to '%s' tag must be 'as'" % bits[0] return ArchiveDatesNode(bits[1], bits[2], kind, varname) get_archive_dates = register.tag(get_archive_dates) def strftime(value, arg=None): "Formats a date according to the given format using datetime.strftime" from django.utils.dateformat import format if not value: return '' if arg is None: arg = settings.DATE_FORMAT return value.strftime(arg) strftime = register.filter(strftime)