Jinja2宏参数不会扩展

时间:2019-12-12 23:48:27

标签: python flask jinja2 flask-wtforms

我有一个定义如下的宏:

{% macro render_row (class_suffix, form, field) %}
<div class="form-{{ class_suffix }}__row">{{ form.field.label }} {{ form.field() }}</div>
{% endmacro %}

我想传递一个form对象和一个field参数来呈现特定的行,如下所示:

{% import "macros.html" as macros %}
...
<div class="form-container">
    <h2>Sign In</h2>
    <form class="form-login" action="{{ url_for('signin') }}" method="post">
        {{ macros.render_row ('login', form, email) }}
        {{ macros.render_row ('login', form, password) }}
        {{ macros.render_submit ('login', 'Sign In') }}
        {{ form.csrf_token }}
    </form>
</div>

例如,macros.render_row ('login', form, email)应扩展为:

<div class="form-login__row">{{ form.email.label }} {{ form.email() }}</div>

相反,我收到此错误:

jinja2.exceptions.UndefinedError: 'blog.forms.SignInForm object' has no attribute 'field'

表单的定义如下:

class SignInForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email(), Length(max=64)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=8, max=64)])

我也找到了解决方案,但我很好奇为什么以前的方法不起作用。

{% macro render_row (class_suffix, form_field) %}
<div class="form-{{ class_suffix }}__row">{{ form_field.label }} {{ form_field() }}</div>
{% endmacro %}
...
{{ macros.render_row ('login', form.email) }}

有可能吗?我究竟做错了什么?做这样的事情甚至是个好习惯吗?

1 个答案:

答案 0 :(得分:1)

这是因为Jinja2试图从传递的表单对象中获取名为field的属性,而不是与传递的变量field相等的字段。

它试图做

{{ foo.field }}
{{ foo['field'] }}

但是对于您的情况,当然只有使用此语法才能使用。

{{ foo[field] }}

我相信宏的field参数应该是字符串,现在我认为是None

应该是

{{ macros.render_row ('login', form, 'email') }}

以及类似宏的定义

{% macro render_row (class_suffix, form, field) %}
<div class="form-{{ class_suffix }}__row">{{ form[field].label }} {{ form[field]() }}</div>
{% endmacro %}

在变量的语法页面https://jinja.palletsprojects.com/en/2.10.x/templates/#variables上查看更多详细信息。

  

我还没有在真实文件中测试过它,还没有安装Jinja2。但是它应该可以那样工作。