Jinja2模板中字典的格式化与使用

4 投票
2 回答
3829 浏览
提问于 2025-04-18 00:27

我正在尝试把两个字典 form_labelform_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
} 

你需要先定义名为 keyvalue 的变量,所以实际上

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”。这样可能会让解析器感到困惑。

撰写回答