Flask目录:https://www.jianshu.com/p/9b5e30320849
概述
flask的表单操作也是依赖于其他组件,我们这里主要讲解Flask-WTF与wftforms。
Flask-WTF与WTFforms
安装:python -m pip install Flask-WTF
Flask-WTF的特点
避免重复操作, 表单操作很多;
防止表单遭遇跨站请求伪造(csrf===cross-site request forgery);
Flask-WTF扩展使得处理web表单能获得更愉快的体验。该扩展是一个封装了与框架无关的WTForms包的Flask集成。
常用的WTForms字段
字段 | 用途 |
---|---|
BooleanField | 复选框,值为True或者False |
DateField | 文本字段,格式要求为datetime.date一样 |
DateTimeField | 文本字段,格式要求为datetime.datetime一样 |
FloatField | 浮点数字段,值是浮点数 |
FileField | 文件上传字段 |
IntergerField | 整数字段,格式要求是整数 |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMultipleField | 多选下拉列表 |
SubmitField | 提交按钮 |
StringField | 文本字段 |
HiddenField | 隐藏文本字段 |
PasswordField | 密码字段,自动将输入转化为小黑点 |
TextAreaField | 多行文本字段 |
常用参数
参数 | 说明 |
---|---|
label | 别名 |
Validator | 校验器 |
default | 默认值 |
校验器常用参数
__all__ = (
'DataRequired', 'data_required', 'Email', 'email', 'EqualTo', 'equal_to',
'IPAddress', 'ip_address', 'InputRequired', 'input_required', 'Length',
'length', 'NumberRange', 'number_range', 'Optional', 'optional',
'Required', 'required', 'Regexp', 'regexp', 'URL', 'url', 'AnyOf',
'any_of', 'NoneOf', 'none_of', 'MacAddress', 'mac_address', 'UUID'
)
参数 | 说明 |
---|---|
DataRequired | data_required:验证数据是否真实存在,即不能为空,必须是非空白字符串,否则触发StopValidation错误。 |
InputRequired | input_required:和DataRequired的区别在于可以是空白字符串; |
Required | required:data_required的别名 |
email:验证符合邮件的格式,只有最基本的验证; | |
EqualTo | equal_to:比较两个字段的值,比如密码和确认密码,如果不相等就触发错误,equal_to(field,message),需要输入另一个字段的名字。 |
IPAddress | ip_address:验证是否是ip地址,默认验证IPV4地址。 |
MacAddress | mac_address:验证是否符合mac格式; |
UUID | 是否是uuid格式; |
URL | url:验证是否符合url格式; |
Regexp | regexp:用提供的正则表达式验证字段;Regexp(r"") |
Length | length:设置字段值的长度,Length(min,max); |
NumberRange | number_range:设置一个数字字段的取值范围,可以针对浮点数和小数;NumberRange(min,max) |
Optional | optional:允许字段为空并停止验证; |
NoneOf | none_of:将传入的数据和无效的比较,是抛出异常;Noneof(values). |
Anyof | any_of:将传入的数据和预设的数据比较,不是异常。Anyof(values). |
登录注册实例
app.py
------
from flask import Flask, render_template, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from forms import LoginForm, UserForm
app = Flask(__name__)
# 配置数据库的连接参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root: @127.0.0.1/test_flasks'
app.config['WTF_CSRF_SECRET_KEY'] = 'abcd12321'
app.config['SECRET_KEY'] = 'CCSDFS'
db = SQLAlchemy(app)
class User(db.Model):
""" 用户ID """
__tablename__ = 'wei_user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), nullable=False)
password = db.Column(db.String(255), nullable=False)
birth_date = db.Column(db.Date, nullable=True)
age = db.Column(db.Integer, default=0)
@app.route('/')
def index():
return render_template('index.html')
#登录
@app.route('/user', methods=['GET', 'POST'])
def form_user():
""" 登录 """
form = LoginForm()
if form.validate_on_submit():
# 获取表单数据
username = form.username.data
password = form.password.data
user = db.session.query(User).filter_by(username=username,password=password).first()
if user:
# 提示/跳转
print('登录成功')
return redirect(url_for('index'))
else:
print('表单验证未通过')
print(form.errors)
return render_template('form.html', form=form)
#注册
@app.route('/user/add', methods=['GET', 'POST'])
def add_user():
""" 注册 """
form = UserForm()
if form.validate_on_submit():
# 获取表单数据
username = form.username.data
password = form.password.data
birth_date = form.birth_date.data
age = form.age.data
# 保存到数据
user = User(username=username,
password=password,
birth_date=birth_date,
age=age)
db.session.add(user)
db.session.commit()
# 提示/跳转
print('添加成功')
return redirect(url_for('index'))
else:
print('表单验证未通过')
print(form.errors)
return render_template('add_user.html', form=form)
form.py
-------
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, DateField, IntegerField
class LoginForm(FlaskForm):
""" 用户登录 """
username = StringField(label='用户名')
password = PasswordField(label='密码')
submit = SubmitField('登录')
class UserForm(FlaskForm):
""" 新增用户 """
username = StringField(label='用户名')
password = PasswordField(label='密码')
birth_date = DateField(label='生日')
age = IntegerField(label='年龄')
submit = SubmitField('新增')
form.html
---------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>form表单的使用</title>
</head>
<body>
<form action="{{ url_for('form_user') }}" method="post">
{{ form.csrf_token }}
<p>{{ form.username.label }}:{{ form.username }}</p>
<p>{{ form.password.label }}:{{ form.password }}</p>
{{ form.submit }}
</form>
</body>
</html>
add_user.html
-------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加新用户</title>
</head>
<body>
<form action="{{ url_for('add_user') }}" method="post">
{{ form.csrf_token }}
<p>
{{ form.username.label }}
{{ form.username }}
</p>
<p>
{{ form.password.label }}
{{ form.password }}
</p>
<p>
{{ form.birth_date.label }}
{{ form.birth_date }}
</p>
<p>
{{ form.age.label }}
{{ form.age }}
</p>
<p>
{{ form.submit }}
</p>
</form>
</body>
</html>
登录注册校验实例
import re
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, DateField, IntegerField
from wtforms.validators import DataRequired, ValidationError
def phone_required(form, field):
""" 自定义的验证 """
username = field.data
# 强制用户名为手机号码
pattern = r'^1[0-9]{10}$'
if not re.search(pattern, username):
raise ValidationError('请输入手机号码')
return field
class LoginForm(FlaskForm):
""" 用户登录 """
username = StringField(label='用户名', validators=[
phone_required
])
password = PasswordField(label='密码')
submit = SubmitField('登录')
class UserForm(FlaskForm):
""" 新增用户 """
username = StringField(label='用户名', validators=[
phone_required
])
password = PasswordField(label='密码')
birth_date = DateField(label='生日', validators=[DataRequired('请输入生日')])
age = IntegerField(label='年龄')
submit = SubmitField('新增')
add_user.html
--------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加新用户</title>
</head>
<body>
<form action="{{ url_for('add_user') }}" method="post" novalidate>
{{ form.csrf_token }}
<p>
{{ form.username.label }}
{{ form.username }}
{% if form.username.errors %}
{% for err in form.username.errors %}
{{ err }}
{% endfor %}
{% endif %}
</p>
<p>
{{ form.password.label }}
{{ form.password }}
</p>
<p>
{{ form.birth_date.label }}
{{ form.birth_date }}
</p>
<p>
{{ form.age.label }}
{{ form.age }}
</p>
<p>
{{ form.submit }}
</p>
</form>
</body>
</html>
文件上传
我们接着用两个实例来演示,第一个实例是使用form表单实现:
import os
from flask import Flask, render_template,request
from werkzeug.utils import secure_filename
app = Flask(__name__)
app.config['UPLOAD_PATH'] = os.path.join(os.path.dirname(__file__), 'medias')
@app.route('/img/upload', methods=['GET', 'POST'])
def img_upload():
""" 图片上传 """
if request.method == 'POST':
# 取文件
files = request.files
file1 = files['file1']
# 保存文件
if file1:
# 文件名称格式化
filename = secure_filename(file1.filename)
file_name = os.path.join(app.config['UPLOAD_PATH'], filename)
file1.save(file_name)
return render_template('img_upload.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片上传</title>
</head>
<body>
<form action="{{ url_for('img_upload') }}" method="post" enctype="multipart/form-data">
<input type="file" name="file1">
<input type="submit" value="点击上传">
</form>
</body>
</html>
第二种是使用了flask-wtf:
import os
from flask import Flask, render_template,request
from werkzeug.utils import secure_filename
from forms import UserAvatarForm
app = Flask(__name__)
app.config['UPLOAD_PATH'] = os.path.join(os.path.dirname(__file__), 'medias')
@app.route('/avatar/upload', methods=['GET', 'POST'])
def avatar_upload():
""" 头像上传 """
form = UserAvatarForm()
if form.validate_on_submit():
f = form.avatar.data
filename = secure_filename(f.filename)
file_name = os.path.join(app.config['UPLOAD_PATH'], filename)
f.save(file_name)
print('上传头像成功')
else:
print(form.errors)
return render_template('avatar_upload.html', form=form)
form.py
-------
import re
from flask_wtf import FlaskForm
from flask_wtf.file import FileRequired, FileAllowed, FileField
class UserAvatarForm(FlaskForm):
avatar = FileField(label='上传头像', validators=[
FileRequired('请选择图片文件'),
FileAllowed(['png'], '仅支持png')
])
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>头像上传</title>
</head>
<body>
<form action="{{ url_for('avatar_upload') }}" method="post" enctype="multipart/form-data">
{{ form.avatar }}
{{ form.csrf_token }}
<input type="submit" value="点击上传">
</form>
</body>
</html>
网友评论