根据属性值显示jinja2表单域

时间:2016-02-25 19:35:54

标签: python flask jinja2

我正在使用烧瓶应用并使用flask-wtf来帮助管理我的表单。

我的网站上有两种注册方式 - 无论是否有电子邮件令牌。

如果确认电子邮件,则用户会收到包含以下内容的电子邮件:

http://127.0.0.1:5000/register/ImNsdWVtYXJpbmUzQG1haWxpbmF0b3IuY29tIg.Ca9oUQ.bRJmGYQ1wNqfcQFx1pYyoCEy2oM

否则,在网站上,用户可以点击:

 http://127.0.0.1:5000/register

以下代码可以处理这两种情况:

@blueprint.route("/register/", defaults={'token': ''}, methods=['GET', 'POST'])
@blueprint.route("/register/<token>", methods=['GET', 'POST'])
def register(token):
    form = RegisterForm(request.form, csrf_enabled=False)
    email = confirm_token(token)
    if form.validate_on_submit():
        new_user = User.create(username=form.username.data,
                              email=form.email.data,
                               password=form.password.data,
                               active=True)
return render_extensions('public/register.html', form=form , email=email)

我的表单类似乎:

class RegisterForm(Form):
    username = StringField('Username', validators=[DataRequired(), Length(min=3, max=25)])
    email = StringField('Email', validators=[DataRequired(), Email(), Length(min=6, max=40)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=40)])

我有一个jinja2表单模板,如下所示:

{% from "macros.html" import render_field  %}
<div class="container-narrow">
  <h1>Register</h1>
    <br/>
       <form id="registerForm" class="form form-register" method="POST" action="" role="form">
        {{ form.hidden_tag() }}
        {% for field in form %}
            {% if field.label!='Email' or email=='False' %}
                {{ render_field(field) }}
            {% endif %}
        {% endfor %}
        <p><input class="btn btn-default btn-submit" type="submit" value="Register"></p>
</div>
{% endblock %}

和jinja2宏看起来像:

{% macro render_field(field)%}

<div class="form-group">
{#                {{field.label}}#}
                {{field(placeholder=field.label.text, class_="form-control")}}
</div>

{% endmacro %}

现在这段代码可以显示registerForm类中的所有字段。我想修改/过滤它,以便在使用令牌时,我想只显示和验证2个表单字段(用户名,密码)。如果没有令牌 - 全部3。怎么办呢?

编辑:切换

{% if field.label!='Email' or email=='False' %}

{% if field.label.text!='Email' or email=='False' %}

让它运作

1 个答案:

答案 0 :(得分:1)

一种选择是使用继承,我们定义了两个表单类:

class TokenRegisterForm(Form):

    username = StringField('Username', 
        validators=[DataRequired(), Length(min=3, max=25)])

    password = PasswordField('Password', 
        validators=[DataRequired(), Length(min=6, max=40)])


class RegisterForm(TokenRegister):

    email = StringField('Email',
        validators=[DataRequired(), Email(), Length(min=6, max=40)])

然后我们修改视图以根据令牌的存在选择要使用的表单:

def register(token):
    """Register a user"""

    # Create the registration form based on the presence of a token. If the user 
    # has specified a valid token then we can use that to get retrieve their 
    # email address, if not we need to the registration form to ask it.
    email = confirm_token(token)
    if email:
        form = TokenRegisterForm(request.form, csrf_enabled=False)
    else
        form = RegisterForm(request.form, csrf_enabled=False)

    # Validate the user's submission
    if form.validate_on_submit():

        # Collate the details for the new user
        user_details = form.data
        user_details['active'] = True
        if email:
            user_details['email'] = email

        # Create the new user
        new_user = User.create(**user_details)

    return render_extensions('public/register.html', form=form, email=email)

最后我们修改Jinja2模板删除循环(因为它是一个如此简短的形式):

{% from "macros.html" import render_field  %}

<div class="container-narrow">
    <h1>Register</h1>
    <br/>
    <form 
        class="form form-register" 
        id="registerForm" 
        method="POST"
        role="form"
        >
        {{ form.hidden_tag() }}
        {{ render_field(field.username) }}
        {% if form.email %}
            {{ render_field(field.email) }}
        {% endif %}
        {{ render_field(field.password) }}
        <p>
            <input 
                class="btn btn-default btn-submit" 
                type="submit" 
                value="Register">
        </p>
</div>