根据属性值显示 jinja2 表单字段
Displaying jinja2 form fields based on attribute value
我正在开发一个 flask 应用程序并使用 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 看起来像:
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 中的所有字段 class。我想 modify/filter 它以便如果使用令牌,我只想显示和验证 2 个表单字段 (username, password) 。如果没有令牌 - 所有 3。这怎么能做到?
编辑:切换
{% if field.label!='Email' or email=='False' %}
到
{% if field.label.text!='Email' or email=='False' %}
成功了
一个选择是使用继承,我们定义 2 种形式 类:
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>
我正在开发一个 flask 应用程序并使用 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 看起来像:
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 中的所有字段 class。我想 modify/filter 它以便如果使用令牌,我只想显示和验证 2 个表单字段 (username, password) 。如果没有令牌 - 所有 3。这怎么能做到?
编辑:切换
{% if field.label!='Email' or email=='False' %}
到
{% if field.label.text!='Email' or email=='False' %}
成功了
一个选择是使用继承,我们定义 2 种形式 类:
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>