from django.template import Library from functools import partial register = Library() @register.filter def method(value, arg): """ Prepare the specified object for invoking a method. This is used in conjunction with the "with" and "call" tags. For example, with class Foo: def bar(self, a, b, c): return "a is %s, b is %b, c is %c" % (a, b, c) def bop(self, a): return "a is %s" % a and { "foo": Foo() } passed to the template, then: foo|method:"bar"|with:"one"|with:"two"|with:"three"|call will invoke foo("one", "two", "three"), and emit: a is one, b is two, c is three. Alternatively, foo|method:"bop"|call_with:"baz" is a bit of a short cut. """ if hasattr(value, str(arg)): return getattr(value, str(arg)) return "[%s has no method %s]" % (value, arg) @register.filter def call_with(value, arg): """ Call a function with the specified argument. Meant to be used with the "method" tag. """ if not callable(value): return "[%s is not callable]" % value return value(arg) @register.filter def call(value): """ Call a function with no arguments. Meant to be used with the "method" tag. """ if not callable(value): return "[%s is not callable]" % value return value() @register.filter(name="with") def with_(value, arg): """ Accumulate the specified positional argument. Meant to be used with the "method" tag. """ if callable(value): return partial(value, arg) return "[%s is not callable]" % value