Djangoテンプレートをデバッグするためのラベル
詳細
Djangoテンプレートには、メソッドを呼び出すことができず、任意のPython式を実行できないなど、多くの制限があります.その設計者はわざとやったと言っていますが、これが良いのか悪いのかは議論しませんが、デバッグ時に任意のPython式を実行する必要があります.Djangoはラベルをカスタマイズするメカニズムを提供し、Pythonのeval関数を加えることで、Djangoテンプレートでも任意のPython式を実行することができます.
set,print,importの3つのラベルを書きました.setの構文は次のとおりです.
python_が実行されますexpressionの値をテンプレートコンテキストに追加し、varnameで参照できます.
python_expressionは任意のPython式であり、テンプレートコンテキストの変数を使用することができます.
views.py
test.html
出力:
printラベルはもっと簡単です.文法は次のとおりです.
python_を直接出力しますexpressionの値.上のテストhtmlは次のように書くことができます.
importラベルは、その名の通り、Pythonモジュールをインポートするために使用されます.構文は次のとおりです.
test.html
これらの実装は簡単で、直接ここに添付されています.
Djangoテンプレートには、メソッドを呼び出すことができず、任意のPython式を実行できないなど、多くの制限があります.その設計者はわざとやったと言っていますが、これが良いのか悪いのかは議論しませんが、デバッグ時に任意のPython式を実行する必要があります.Djangoはラベルをカスタマイズするメカニズムを提供し、Pythonのeval関数を加えることで、Djangoテンプレートでも任意のPython式を実行することができます.
set,print,importの3つのラベルを書きました.setの構文は次のとおりです.
{% set varname = python_expression %}
python_が実行されますexpressionの値をテンプレートコンテキストに追加し、varnameで参照できます.
python_expressionは任意のPython式であり、テンプレートコンテキストの変数を使用することができます.
views.py
return render_to_response('test.html' {
'list': ['a', 'b', 'c'],
'num': 25,
'name': 'marlon',
})
test.html
{% set len = len(list) %}
length of list: {{ len }}
{% set a = num + len %}
Now num value: {{ a }}
出力:
length of list: 3
Now num value: 28
printラベルはもっと簡単です.文法は次のとおりです.
{% print python_expression %}
python_を直接出力しますexpressionの値.上のテストhtmlは次のように書くことができます.
length of list: {% print len(list) %}
Now num value: {% print num + len %}
importラベルは、その名の通り、Pythonモジュールをインポートするために使用されます.構文は次のとおりです.
{% import import_expression [ as alias_name ] %}
test.html
{% import sys %}
{% print sys.path %}
これらの実装は簡単で、直接ここに添付されています.
from django import template
import re
register = template.Library()
set_regex = re.compile(r'^\s*set\s+(\w+)\s*=\s*(.*)$')
def do_set(parser, token):
m = re.match(set_regex, token.contents)
if m:
name, exp = m.group(1), m.group(2)
return SetNode(name, exp)
else:
raise template.TemplateSyntaxError('{% set varname = python_expression %}')
class SetNode(template.Node):
def __init__(self, varname, expression):
self.varname = varname
self.expression = expression
def render(self, context):
context[self.varname] = eval(self.expression, {}, context)
return ''
register.tag('set', do_set)
print_regex = re.compile(r'^\s*print\s+(.*)$')
def do_print(parser, token):
m = re.match(print_regex, token.contents)
if m:
exp = m.group(1)
return PrintNode(exp)
else:
raise template.TemplateSyntaxError('{% print expression %}')
class PrintNode(template.Node):
def __init__(self, expression):
self.expression = expression
def render(self, context):
obj = eval(self.expression, {}, context)
return str(obj)
register.tag('print', do_print)
import_regex = re.compile(r'^\s*import\s+(\S+)(?:\s+as\s+(\w+))?$')
def do_import(parser, token):
m = re.match(import_regex, token.contents)
if m:
exp = m.group(1)
try:
alias = m.group(2)
except:
alias = None
return ImportNode(exp, alias)
else:
raise template.TemplateSyntaxError('{% import import_expression [ as alias_name ] %}')
class ImportNode(template.Node):
def __init__(self, expression, alias=None):
if not alias: alias = expression
self.expression = expression
self.alias = alias
def render(self, context):
module = __import__(self.expression, {}, context)
context[self.alias] = module
return ''
register.tag('import', do_import)