Login

PyCallTag - Directly call python function or attribute of a module

Author:
limodou
Posted:
February 25, 2007
Language:
Python
Version:
Pre .96
Score:
4 (after 6 ratings)

How to use it

{% pycall os.path.abspath(".") %}
{% pycall os.path.abspath(".") as path %}
This is the {{ path }}.

Syntax

{% pycall module.function(...) [as variable_name] %}

If there is no as variable_name, the result will be output directly.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from django import template
from django.utils.translation import gettext_lazy as _
import re

register = template.Library()

r_identifers = re.compile(r'[\w.]+')
class PyCallNode(template.Node):
    def __init__(self, expr_string, var_name):
        self.expr_string = expr_string
        self.var_name = var_name

    def __repr__(self):
        return "<PyCall node>"

    def render(self, context):
        clist = list(context)
        clist.reverse()
        d = {}
        d['_'] = _
        for c in clist:
            d.update(c)
        m = r_identifers.match(self.expr_string)
        if m:
            module, func = m.group().rsplit('.', 1)
            funcstring = self.expr_string[len(module) + 1:]
            mod = __import__(module, {}, {}, [''])
            d[func] = getattr(mod, func)
        else:
            raise template.TemplateSyntaxError, "The arguments of %r tag should be module.function(...)" % 'pycall'
            
        if self.var_name:
            context[self.var_name] = eval(funcstring, d)
            return ''
        else:
            return str(eval(funcstring, d))

def do_pycall(parser, token):
    try:
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents[0]
    
    m = re.search(r'(.*?)\s+as\s+(\w+)', arg)
    if m:
        expr_string, var_name = m.groups()
    else:
        if not arg:
            raise template.TemplateSyntaxError, "The arguments of %r tag should be module.function(...)" % tag_name
            
        expr_string, var_name = arg, None
            
    return PyCallNode(expr_string, var_name)
do_pycall = register.tag("pycall", do_pycall)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

cricogik (on December 20, 2010):

Good programmers don't use eval ;-) Rest of them had to heavy childhood.

#

Please login first before commenting.