Flask 系列之 FlaskForm
通过使用 FlaskForm ,可以方便快捷的实现表单处理。
说明
- 操作系统:Windows 10
- Python 版本:3.7x
- 虚拟环境管理器:virtualenv
- 代码编辑器:VS Code
实验目标
通过使用 flask_wtf 进行表单的相关操作,并完成新用户合法性注册。
安装
pip install flask_wtf
使用
首先,我们在 todolist
目录中创建一个 forms.py 文件,定义一个注册的表单类, 用于完成用户注册。示例代码如下所示:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TextAreaField, PasswordField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from models import User
class RegisterForm(FlaskForm):
username = StringField('用户名:', validators=[
DataRequired(), Length(min=6, max=20)])
email = StringField('邮箱:', validators=[DataRequired(), Email()])
pwd = PasswordField('密码:', validators=[
DataRequired(), Length(min=8, max=120)])
confirm = PasswordField('确认密码:', validators=[
DataRequired(), EqualTo('pwd')])
submit = SubmitField('提交')
def validate_username(self, username):
user = User.query.filter_by(name=username.data).first()
if user:
raise ValidationError("用户昵称已存在。")
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user:
raise ValidationError('邮箱已存在.')
然后修改我们的路由视图 todolist\app\views.py
,示例代码如下所示:
from flask import render_template, redirect, url_for, flash
from werkzeug.security import generate_password_hash
from app import app, db
from forms import RegisterForm
from models import User
@app.route('/')
@app.route('/index')
def index():
return render_template('index.html', title="首页")
@app.route('/login')
def login():
return render_template('login.html', title='登录')
@app.route('/register', methods=['POST', 'GET'])
def register():
form = RegisterForm()
if form.validate_on_submit():
username = form.username.data
email = form.email.data
pwd = form.pwd.data
print(username, email, pwd)
hash = generate_password_hash(pwd)
user = User(name=username, email=email, pwd=pwd)
db.session.add(user)
db.session.commit()
flash('注册成功', category='info')
return redirect(url_for('login'))
return render_template('register.html', title='注册', form=form)
然后,修改 todolist\app\templates\base.html
,添加闪现消息,示例代码如下所示:
<!doctype html>
<html lang="en">
<head>
{% block head %}
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> {% block styles %}
<!-- Bootstrap CSS -->
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}"> {{ bootstrap.load_css() }} {% endblock %}
{% if title %}
<title>{{title}}</title>
{% else %}
<title>愿望清单</title>
{% endif %} {% endblock %}
</head>
<body>
{% include "nav.html" %}
<div class="container">
{% for message in get_flashed_messages() %}
<div class="alert alert-primary" role="alert">
{{ message }}
</div>
{% endfor %}
<!-- Your page contont -->
{% block content %}{% endblock%}
</div>
{% block scripts %}
<!-- Optional JavaScript -->
{{ bootstrap.load_js() }} {% endblock %}
</body>
</html>
接着,完善 todolist\app\templates\register.html
中的注册表单,示例代码如下所示:
{% extends 'base.html' %} {% block content %}
<h1>注册页面</h1>
{% from 'bootstrap/form.html' import render_form %}
{{ render_form(form) }}
{% endblock %}
注:由于我们使用了 flask_bootstrap 插件,所有我们可以直接通过它来渲染出我们的表单。
最后,由于表单提交会涉及 跨域访问问题 CSRF,所以我们需要修改我们的 todolist\config.py
文件,添加一个 SECRET_KEY 字段,示例代码如下所示:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SQLALCHEMY_DATABASE_URI = os.environ.get(
'SQLALCHEMY_DATABASE_URI') or 'mysql+pymysql://root:mysql@127.0.0.1:3306/todo'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = "you will never known it."
此时,当我们运行起我们的网站后进入注册页面 http://127.0.0.1:5000/register 进行用户注册,如果注册完成后自动跳转到登陆页面则表示用户注册已经可以正常运行了。