Flask wtf 表单不验证自定义验证器
Flask wtf form not validating custom validators
所以我在一个 html 页面上有一个登录表单和注册表单。我的注册表单自定义验证器不起作用。
routes.py 看起来像这样
@app.route("/", methods=['GET', 'POST'])
def home():
login_form = LoginForm(request.form, prefix="login-form")
regis_form = RegistrationForm(request.form, prefix="register-form")
return render_template('home.html', login_form=login_form, regis_form=regis_form)
@app.route("/register", methods=['POST'])
def register():
regis_form = RegistrationForm(request.form, prefix='register-form')
if regis_form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(regis_form.password_regis.data).decode('utf-8')
user = User(username=regis_form.username_regis.data, email=regis_form.email_regis.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('home'))
return redirect(url_for('home'))
@app.route("/login", methods=['POST'])
def login():
login_form = LoginForm(request.form, prefix='login-form')
if login_form.validate_on_submit():
user = User.query.filter_by(email=login_form.email_login.data).first()
if user and bcrypt.check_password_hash(user.password, login_form.password_login.data):
login_user(user, remember=login_form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return redirect(url_for('home'))
forms.py
class RegistrationForm(FlaskForm):
username_regis = StringField('Username',
validators=[DataRequired(), Length(min=5, max=20)])
email_regis = EmailField('Email',
validators=[DataRequired(), Email()])
password_regis = PasswordField('Password', validators=[DataRequired()])
submit_regis = SubmitField('Sign Up')
def validate_username_regis(self, username_regis):
user = User.query.filter_by(username=username_regis.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one.')
def validate_email_regis(self, email_regis):
user = User.query.filter_by(email=email_regis.data).first()
if user:
raise ValidationError('That email is taken. Please choose a different one.')
class LoginForm(FlaskForm):
email_login = EmailField('Email',
validators=[DataRequired(), Email()])
password_login = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit_login = SubmitField('Login')
home.html
<div>
<form method="POST" action="{{ url_for('login') }}">
{{ login_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if login_form.email_login.errors %}
{{ login_form.email_login(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.email_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.email_login(class="form-control mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if login_form.password_login.errors %}
{{ login_form.password_login(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.password_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.password_login(class="form-control mb-2", placeholder="Password") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ login_form.submit_login(class="btn btn-danger") }}
</div>
</form>
</div>
<div class="" id="regis">
<form method="POST" action="{{ url_for('register') }}">
{{ regis_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if regis_form.username_regis.errors %}
{{ regis_form.username_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.username_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.username_regis(class="form-control form-control-md mb-2", placeholder="Username") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.email_regis.errors %}
{{ regis_form.email_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.email_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.email_regis(class="form-control form-control-md mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.password_regis.errors %}
{{ regis_form.password_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.password_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.password_regis(class="form-control form-control-md mb-2", placeholder="Password") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ regis_form.submit_regis(class="btn btn-danger") }}
</div>
</form>
</div>
以前我在同一条 home 路线上有两个表单,自定义验证器正在工作,但如果我提交 register 表单有目的地有错误,然后登录表单也显示错误,如 input required。所以为了解决这个问题,我这样做了,但现在注册表单没有验证自定义验证器
数据验证失败后,执行return redirect(url_for('home'))
。这导致在主路线上出现 GET
。这会填充一个新的表单实例:regis_form = RegistrationForm(request.form, prefix="register-form")
。您的错误信息将丢失,它在不同的实例上。
要获取错误信息,您的 register()
路由将需要 render
使用 render_template('home.html', login_form=login_form, regis_form=regis_form)
的模板,而不是进行重定向。不要忘记创建 LoginForm
的新实例,否则渲染将失败。
所以我在一个 html 页面上有一个登录表单和注册表单。我的注册表单自定义验证器不起作用。 routes.py 看起来像这样
@app.route("/", methods=['GET', 'POST'])
def home():
login_form = LoginForm(request.form, prefix="login-form")
regis_form = RegistrationForm(request.form, prefix="register-form")
return render_template('home.html', login_form=login_form, regis_form=regis_form)
@app.route("/register", methods=['POST'])
def register():
regis_form = RegistrationForm(request.form, prefix='register-form')
if regis_form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(regis_form.password_regis.data).decode('utf-8')
user = User(username=regis_form.username_regis.data, email=regis_form.email_regis.data, password=hashed_password)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('home'))
return redirect(url_for('home'))
@app.route("/login", methods=['POST'])
def login():
login_form = LoginForm(request.form, prefix='login-form')
if login_form.validate_on_submit():
user = User.query.filter_by(email=login_form.email_login.data).first()
if user and bcrypt.check_password_hash(user.password, login_form.password_login.data):
login_user(user, remember=login_form.remember.data)
next_page = request.args.get('next')
return redirect(next_page) if next_page else redirect(url_for('home'))
else:
flash('Login Unsuccessful. Please check email and password', 'danger')
return redirect(url_for('home'))
forms.py
class RegistrationForm(FlaskForm):
username_regis = StringField('Username',
validators=[DataRequired(), Length(min=5, max=20)])
email_regis = EmailField('Email',
validators=[DataRequired(), Email()])
password_regis = PasswordField('Password', validators=[DataRequired()])
submit_regis = SubmitField('Sign Up')
def validate_username_regis(self, username_regis):
user = User.query.filter_by(username=username_regis.data).first()
if user:
raise ValidationError('That username is taken. Please choose a different one.')
def validate_email_regis(self, email_regis):
user = User.query.filter_by(email=email_regis.data).first()
if user:
raise ValidationError('That email is taken. Please choose a different one.')
class LoginForm(FlaskForm):
email_login = EmailField('Email',
validators=[DataRequired(), Email()])
password_login = PasswordField('Password', validators=[DataRequired()])
remember = BooleanField('Remember Me')
submit_login = SubmitField('Login')
home.html
<div>
<form method="POST" action="{{ url_for('login') }}">
{{ login_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if login_form.email_login.errors %}
{{ login_form.email_login(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.email_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.email_login(class="form-control mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if login_form.password_login.errors %}
{{ login_form.password_login(class="form-control is-invalid") }}
<div class="invalid-feedback">
{% for error in login_form.password_login.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ login_form.password_login(class="form-control mb-2", placeholder="Password") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ login_form.submit_login(class="btn btn-danger") }}
</div>
</form>
</div>
<div class="" id="regis">
<form method="POST" action="{{ url_for('register') }}">
{{ regis_form.hidden_tag() }}
<fieldset class="form-group">
<div class="form-group">
{% if regis_form.username_regis.errors %}
{{ regis_form.username_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.username_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.username_regis(class="form-control form-control-md mb-2", placeholder="Username") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.email_regis.errors %}
{{ regis_form.email_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.email_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.email_regis(class="form-control form-control-md mb-2", placeholder="Email") }}
{% endif %}
</div>
<div class="form-group">
{% if regis_form.password_regis.errors %}
{{ regis_form.password_regis(class="form-control form-control-md is-invalid") }}
<div class="invalid-feedback">
{% for error in regis_form.password_regis.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ regis_form.password_regis(class="form-control form-control-md mb-2", placeholder="Password") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ regis_form.submit_regis(class="btn btn-danger") }}
</div>
</form>
</div>
以前我在同一条 home 路线上有两个表单,自定义验证器正在工作,但如果我提交 register 表单有目的地有错误,然后登录表单也显示错误,如 input required。所以为了解决这个问题,我这样做了,但现在注册表单没有验证自定义验证器
数据验证失败后,执行return redirect(url_for('home'))
。这导致在主路线上出现 GET
。这会填充一个新的表单实例:regis_form = RegistrationForm(request.form, prefix="register-form")
。您的错误信息将丢失,它在不同的实例上。
要获取错误信息,您的 register()
路由将需要 render
使用 render_template('home.html', login_form=login_form, regis_form=regis_form)
的模板,而不是进行重定向。不要忘记创建 LoginForm
的新实例,否则渲染将失败。