Subscribed unsubscribe Subscribe Subscribe

で、こういうことをやってくれるのが欲しい

python django templatetags
from django.utils.html import escape # XXX: 忘れがち
from django.utils.functional import curry # XXX: 残さず食べたくなる
from django.utils.translation import gettext # XXX: ngettext() も
from django.template import Library, Node, TemplateSyntaxError, TokenParser, resolve_variable

register = Library()

# TODO: まだソートできるようにはなってない

# XXX: TokenParser はなぜに内部イテレータ?
class SortableListHeaderTokenParser(TokenParser):
    def top(self):
        values = []
        while True:
            values.append(self.value())
            if not self.more():
                break
        return values

class SortableListHeaderNode(Node):
    def __init__(self, obj, *fields):
        self.obj = obj
        self.fields = fields

    def render_header_column(self, obj, name):
        retval = ''
        retval += '<th>'
        retval += escape(gettext(obj.model._meta.get_field(name).verbose_name))
        retval += '</th>'
        return retval

    def render(self, context):
        # XXX: 本当は context を遅延束縛した上で遅延評価するようなのが欲しい
        obj = resolve_variable(self.obj, context)
        # XXX: 後で join するほうが速いはずだけど
        return reduce(
            lambda p, i: p + self.render_header_column(obj, i),
            [ resolve_variable(field, context) for field in self.fields ],
            ''
            )

def sortable_list_header(parser, token):
    args = SortableListHeaderTokenParser(token.contents).top()
    return SortableListHeaderNode(*args)

register.tag('sortable_list_header', sortable_list_header)

追記: 内部イテレータが外部イテレータと表記されていたので直しました。