Flask表单
Flask项目开发中针对提交表单的校验,可以使用Flask-WTF扩展库进行快速的字段校验
安装Flask-WTF
pip install flask-wtf
定义form.py文件进行表单验证
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired, EqualTo
class UserRegisterForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired()])
password = StringField('密码', validators=[DataRequired()])
password2 = StringField('确认密码', validators=[DataRequired(), EqualTo('password', '密码不一致')])
submit = SubmitField('提交')
定义注册视图函数
当HTTP请求为GET时,将表单验证对象返回给页面。
当HTTP请求为POST时,通过方法validate_on_submit()方法进行字段校验和提交判断,如果校验失败,则可以从form.errors中获取错误信息。
如果验证通过,则从form.字段.data中获取到字段的值。
@blue.route('/register/', methods=['GET', 'POST'])
def register():
form = UserRegisterForm()
if request.method == 'GET':
return render_template('register.html', form=form)
if request.method == 'POST':
if form.validate_on_submit():
username = form.username.data
password = form.password.data
# 保存
user = User()
user.username = username
password = generate_password_hash(password)
user.password = password
user.save()
return '创建成功'
else:
return render_template('register.html', form=form)
使用表单后,会在模板中自动生成表单标签
在括号中可以自定义属性,包括type、style等
<h2>注册</h2>
<form action="" method="post">
{{ form.csrf_token }}
{{ form.username.label }} : {{ form.username }} <br>
{{ form.password.label }} : {{ form.password(type='password') }} <br>
{{ form.password2.label }} : {{ form.password2(type='password') }} <br>
{{ form.submit }}
</form>
Flask文件上传
模板定义
form表单中定义上传文件的字段,定义type='file'。注意上传的表单中一定要添加enctype="multipart/form-data"参数。
<form action="" method="post" enctype="multipart/form-data">
图片: <input type="file" name="icon"><br>
<input type="submit" value="提交">
</form>
图片保存
图片的保存可以直接通过request.files获取模板中上传的图片,并调用save()方法进行保存。
@blue.route('/icon/', methods=['GET', 'POST'])
def icon():
if request.method == 'GET':
return render_template('icon.html')
if request.method == 'POST':
# 1.获取图片
icon = request.files.get('icon')
# 2.保存图片
# path: E:/workspace/flask/day05/static/media/xxx.jpg
path = os.path.join(MEDIA_PATH, icon.filename)
icon.save(path)
# 3.修改字段
user = User.query.filter(User.username == 'aaa').first()
user.icon = icon.filename
user.save()
return redirect(url_for('user.index'))
图片渲染
案例的场景是修改当前登录系统用户的icons字段,在模板中可以通过current_user参数获取当前登录系统的用户对象,并访问icons属性即可获取到存储在数据库中的图片路径。
<img src="/static/media/{{ user.icon }}" style="width: 500px">
项目结构
manage.py - 项目启动
from flask_script import Manager
from utils.app import create_app
# 获取flask对象app
app = create_app()
# 管理app
manage = Manager(app)
if __name__ == '__main__':
manage.run()
app.py - 初始化项目,加载配置,蓝图注册
from flask import Flask
from utils.config import Conf
from app.views import blue
from app.models import db
from utils.settings import STATIC_PATH, TEMPLATE_PATH
def create_app():
app = Flask(__name__,
static_folder=STATIC_PATH,
template_folder=TEMPLATE_PATH)
# 加载配置
app.config.from_object(Conf)
# 蓝图
app.register_blueprint(blueprint=blue, url_prefix='/user')
# 初始化
db.init_app(app)
return app
config - 配置信息(键值对形式)
from utils.functions import get_sqlalchemy_uri
from utils.settings import DATABASE
class Conf():
SQLALCHEMY_DATABASE_URI = get_sqlalchemy_uri(DATABASE)
SQLALCHEMY_TRACK_MODIFICATIONS = False
PRESERVE_CONTEXT_ON_EXCEPTION = False
SECRET_KEY = 'qwertyuiopasdfghjklzxcvbnm1234567890'
settings.py - 经常修改的详细配置信息 - static、templates、media等路径的配置
import os
# 基础路径
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# static路径
STATIC_PATH = os.path.join(BASE_DIR, 'static')
# templates路径
TEMPLATE_PATH = os.path.join(BASE_DIR, 'templates')
# media路径
MEDIA_PATH = os.path.join(STATIC_PATH, 'media')
DATABASE = {
'NAME': 'flask',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
'ENGINE': 'mysql',
'DRIVER': 'pymysql'
}
在functions.py文件中获得mysql连接
def get_sqlalchemy_uri(DATABASE):
# mysql+pymysql://root:123456@127.0.0.1:3306/flask
user = DATABASE['USER']
password = DATABASE['PASSWORD']
host = DATABASE['HOST']
port = DATABASE['PORT']
name = DATABASE['NAME']
engine = DATABASE['ENGINE']
driver = DATABASE['DRIVER']
return f'{engine}+{driver}://{user}:{password}@{host}:{port}/{name}'
自定义状态码清单
USER_LOGIN_PARAMS_IS_INVALID = {'code': 10001, 'msg': '请填写完整信息'}
USER_LOGIN_USERNAME_OR_PASSWORD_ERROR = {'code': 10002, 'msg': '用户名或者密码错误'}
SUCCESS = {'code': 200, 'msg': '请求成功'}
Flask邮件发送
from flask import Flask
from flask_mail import Mail, Message
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.163.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'ypcc624@163.com'
app.config['MAIL_PASSWORD'] = 'abcd1234'
mail = Mail(app)
@app.route('/send_mail/')
def send_mail():
message = Message('邮件轰炸机', sender=app.config["MAIL_USERNAME"], recipients=["779598160@qq.com"])
message.body = '成功啦,开始轰炸啦'
send_email(message)
return '发送成功'
def send_email(msg):
mail.send(msg)
if __name__ == '__main__':
app.run()
参数以及说明
首先需要开启客户端授权码,并设置授权码。
安装flask-mail
pip install flask-mail
设置的参数定义如下:
MAIL_SERVER: 电子邮件服务器的主机名或IP地址, 默认为localhost
MAIL_PORT: 电子邮件服务器的端口,默认为25
MAIL_USE_TLS: 启用传输层安全协议,默认为False
MAIL_USE_SSL: 启用安全套接层协议, 默认为False
MAIL_USERNAME: 邮件账户的用户名
MAIL_PASSWORD:邮件账户的密码,为在163中设置的授权码