Jinja2模板中字典的格式化与使用
我正在尝试把两个字典 form_label
和 form_field
加入到这个宏调用中,但进展不太顺利。
从模板来看,只有宏那一行跟我的问题真的有关系。让我再强调一下。只有宏那一行跟我的问题真的有关系。
{% block content %}
<div id="edit_profile" class="well-lg">
<fieldset>
<form id="form_edit_profile" class="form-horizontal" action="{{ url|safe }}" method="post">
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
{{ macros.field(form.username, label=_("Username"), form_label={class:"col-xs-2"}, form_field={'placeholder':_("Enter your")+" "+_("Username"), class:"form-control focused required"}) }}
...
还有支持这个宏的代码。(因为我第一次没有把类作为字符串传递,所以这部分已经更新了。)
{% macro field(field, label='', form_label={},form_field={}) -%}
<div class="form-group{% if field.errors %} error{% endif %}">
{% set text = label or field.label.text %}
{% if field.flags.required %}
{{ field.label(text=text + " *", class='control-label '+form_label['class'])}}
{% else %}
{{ field.label(text=text + " ", class='control-label '+form_label['class']) }}
{% endif %}
<div class='col-xs-5'>
{{ field(label, **form_field) }}
{% if field.errors %}
{% for error in field.errors %}
<label for="{{ field.id }}" class="error help-inline">{{ error }}</label>
{% endfor %}
{% endif %}
</div>
</div>
{%- endmacro %}
我在想我是不是错误地引用了这些变量,或者字典的键是不是应该是字符串,或者还有其他我没有考虑到的事情。
我更新了错误追踪信息。
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/lib/basehandler.py", line 89, in dispatch
webapp2.RequestHandler.dispatch(self)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/handlers.py", line 112, in get
return self.render_template('login.html', **params)
File "/Users/me/Documents/Aptana Studio 3 Workspace/project/bp_includes/lib/basehandler.py", line 325, in render_template
self.response.write(self.jinja2.render_template(filename, **kwargs))
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2-2.5.2/webapp2_extras/jinja2.py", line 158, in render_template
return self.environment.get_template(_filename).render(**context)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "bp_content/themes/default/templates/login.html", line 1, in top-level template code
{% extends base_layout %}
TypeError: macro 'field' takes no keyword argument 'placeholder'
2 个回答
1
在使用Python中的字典字面量时,这个问题很常见。
my_dict = {
key: value
}
你需要先定义名为 key
和 value
的变量,所以实际上
key = 1
value = 0
my_dict = {
key: value
}
这会创建你的字典,和下面的代码效果是一样的:
my_dict = {
1 : 0
}
所以如果你想要一个字典,里面的键是 'key'
,你就得把它用引号括起来。
my_dict = {
'key': 'value'
}
Jinja2 模板也是一样的道理:
{% macro field(field, label='', form_label={class:""},form_field={class:""}) -%}
这里有两个问题:
这需要先定义
class
标识符
field
被使用了两次
可以用下面的代码替换:
{% macro field_macro(field, label='', form_label={'class':""},form_field={'class':""}) -%}
当然还有:
{{ field_macro(form.username, label=_("Username"), form_label={'class':"col-xs-2"},
form_field={'placeholder':_("Enter your")+" "+_("Username"),
'class':"form-control focused required"}) }}
这里还有一个需要注意的地方,就是默认函数参数。
如果你在宏中改变了 form_field(在 Jinja 中可以做到),而这个参数是默认的(也就是说没有传入任何值),那么所有其他没有传入参数的调用都会使用这个改变后的值。
4
看起来你是在尝试从一个字典里引用一个变量,但没有用引号把它包起来:
form_label['class']
这可能就是问题所在?另外,
form_label = {'class': ''}
关于注释:
你把宏定义成了“field”,但里面的一个变量也叫“field”。这样可能会让解析器感到困惑。