Flask常用扩展(Extentions)
Flask常用扩展(Extentions)
官网;http://flask.pocoo.org/extensions/
1、Flask-Script
说明: 一个flask终端运行的解析器
安装:pip install flask-script
使用
# 导入类库
from flask_script import Manager
# 创建对象
manager = Manager(app)
# 启动实例
if __name__ == '__main__':
# app.run(debug=True, threaded=True, port=5050, host='0.0.0.0')
#使用manager.py来启动服务
manager.run()
启动
python manage.py runserver
python manage.py runserver -d -r --thread
启动参数
-?,--help # 查看启动设置帮助
-h,--host # 指定主机
-p,--port # 指定端口
--thread # 启动多线程
-d # 开启调试模式
-r # 代码修改后自动加载
2、Flask-Bootstrap
安装:pip install flask-bootstrap
使用
from flask_bootstrap import Bootstrap
bootstrap = Bootstrap(app)
事后配置app:bootstrap.init_app(app)
{% extends 'bootstrap/base.html' %}
主要block
title | title标签
head | head标签
styles | 引入css
metas | 一组meta标签
body | body标签
navbar | 用户自定义导航条
content | 用户自定义内容
scripts | 用户定义的JS
定义项目基础模板
1.从bootcss.com复制一个顺眼的导航条
2.将container-fluid改为container
3.显示反色导航条:navbar-inverse
4.将圆角改为直角:style=“border-radius: 0px;”
5.根据需要定制显示内容
6.修改折叠目标的定位:data-target=".navbar-collapse"
{% extends ‘bootstrap/base.html’ %}
错误页面定制
定义404错误处理函数
@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html')
404.html
{% extends 'base.html' %}
{% block title %}出错了{% endblock %}
{% block pagecontent %}
臣妾实在找不到啊@@
{% endblock %}
反向路由
url_for('var', name='xiaoming', pwd='123456')
url_for('var', name='xiaoming', pwd='123456', _external=True)
加载静态资源
加载图片:
<img src="{{ url_for('static', filename='cluo.jpg') }}">
加载CSS:
{% block styles %} {{ super() }}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='common.css') }}" />
{% endblock %}
加载JS:
{% block scripts %} {{ super() }}
<script type="text/javascript" src="{{ url_for('static', filename='common.js') }}">
</script>
{% endblock %}
3Flask-Mail
说明:是一个邮件发送的扩展库,使用非常方便
安装:pip install flask-mail
基本配置
配置邮箱服务器:
app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER', 'smtp.qq.com')
配置用户名:
app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME', 'xxx@qq.com')
配置密码(或授权码):
app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', '123456')
QQ邮箱的额外配置
app.config['MAIL_DEBUG'] = True # 开启debug,便于调试看信息
app.config['MAIL_SUPPRESS_SEND'] = False # 发送邮件,为True则不发送
app.config['MAIL_SERVER'] = 'smtp.qq.com' # 邮箱服务器
app.config['MAIL_PORT'] = 465 # 端口
app.config['MAIL_USE_SSL'] = True # 重要,qq邮箱需要使用SSL
app.config['MAIL_USE_TLS'] = False # 不需要使用TLS
app.config['MAIL_DEFAULT_SENDER'] = 'xxx61@qq.com' # 填邮箱,默认发送者
定义邮件消息
创建邮件消息
msg = Message(subject=subject, recipients=[to], sender=app.config['MAIL_USERNAME'])
浏览器打开邮件的样式
msg.html = render_template(template, **kwargs)
配置邮件正文
msg.body = render_template(template, **kwargs)
发送邮件
创建邮件对象:mail = Mail(app)
事后配置app:mail.init_app(app)
创建发送线程:thr = Thread(target=async_send_mail, args=[app, msg])
执行发送线程:thr.start()
发送邮件:mail.send(message=msg)
注意此处要独占应用上下文:
# 发送邮件需要程序上下文,新的线程没有上下文,需要手动创建
with app.app_context():
# 发送邮件
mail.send(message=msg)
发送附件
with app.open_resource("image.png") as fp:
msg.attach("image.png", "image/png", fp.read())
4、Flask-WTF
a.原生表单
模板文件login.html
<form method="post" action="{{ url_for('check') }}">
用户名:<input name="username" type="text" />
<input type="submit" value="立即登录" />
</form>
视图函数
#渲染
@app.route('/login/')
def login():
return render_template('login.html')
#校验
@app.route('/check/', methods=['POST'])
def check():
return 'Hello %s !' % request.form['username']
#渲染校验合写
@app.route('/login/', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
return 'Hello %s !' % request.form['username']
一个路由处理时,表单的action属性不用书写,默认提交到当前路由。
b. 说明:WTF是一个用于表单处理的扩展库,提供了CSRF、校验等功能,使用非常方便.
c.安装:pip install flask-wtf
d.使用
导入依赖
导入表单基类:from flask_wtf import FlaskForm
导入控件/字段:from wtforms import StringField, SubmitField
导入验证规则:from wtforms.validators import DataRequired
e.配置CSRF秘钥
app.config[‘SECRET_KEY’] = ‘123456’
f.定义表单类
class NameForm(FlaskForm)
name = StringField(‘用户名’, validators=[DataRequired()])
submit = SubmitField(‘提交’)
# 导入表单基类
from flask_wtf import FlaskForm
# 导入字段类型
from wtforms import StringField, SubmitField
# 导入验证器类
from wtforms.validators import DataRequired
# CSRF需要使用
app.config['SECRET_KEY'] = '123456'
# 定义表单类
class NameForm(FlaskForm):
name = StringField('用户名', validators=[DataRequired()])
submit = SubmitField('提交')
g.视图函数
创建表单对象: form = NameForm()
分配到模板中进行渲染:return render_template(‘form.html’, form=form)
@app.route('/')
def index():
# 创建表单对象
form = NameForm()
# 分配到模板中进行渲染
return render_template('form.html', form=form)
h.模板渲染表单
原生渲染
<form>
{# CSRF的隐藏字段 #}
{{ form.hidden_tag() }}
{# name字段,可以指定id、class等属性,定制显示效果 #}
{{ form.name.label() }}
{{ form.name(id='xxx', class='yyy') }}
{# submit字段 #}
{{ form.submit() }}
</form>
bootstrap渲染
{% extends ‘bootstrap/base.html’ %}
{% import ‘bootstrap/wtf.html’ as wtf %}
渲染表单
{% block content %}
{{ wtf.quick_form(form) }}
{% endblock %}
表单校验
@app.route('/', methods=['GET', 'POST'])
def index():
# 创建表单对象
form = NameForm()
# 表单校验
if form.validate_on_submit():
name = form.name.data
form.name.data = ''
# 分配到模板中进行渲染
return render_template('form.html', form=form, name=name)
重定向
@app.route('/', methods=['GET', 'POST'])
def index():
# 创建表单对象
form = NameForm()
# 表单校验
if form.validate_on_submit():
session['name'] = form.name.data
return redirect(url_for('index'))
name = session.get('name')
# 分配到模板中进行渲染
return render_template('form.html', form=form, name=name)
常见字段类型
StringField | 普通文本字段
SubmitField | 提交按钮
PasswordField | 密码文本字段
HiddenField | 隐藏文本字段
TextAreaField | 多行文本字段
DateField | 文本字段,datetime.date格式
DateTimeField | 文本字段,datetime.datetime格式
IntegerField | 文本字段,值为整数
FloatField | 文本字段,值为小数
BooleanField | 复选框,值为True或False
RadioField | 单选框
SelectField | 下拉框
FileField | 文件上传
常见验证器类
DataRequired | 确保字段有值
Email | 邮箱地址
IPAddress | IP地址
Length | 规定字符长度
EqualTo | 验证两个字段的一致性
URL | 有效的URL
NumberRange | 输入数值的范围
Regexp | 正则验证
自定义字段验证
# 定义表单类
class NameForm(FlaskForm):
name = StringField('用户名', validators=[DataRequired()]) submit = SubmitField('提交')
# 自定义字段验证函数,格式是写一个'validate_字段名'的函数
def validate_name(self, field):
if len(field.data) < 6:
raise ValidationError('用户名长度不能少于6个字符')
5、flash消息
提交flash消息
@app.route('/', methods=['GET', 'POST'])
def index():
# 创建表单对象
form = NameForm()
# 表单校验
if form.validate_on_submit():
last_name = session.get('name')
# 原来有名字,并且与新的不同
if last_name and last_name != form.name.data:
# flash消息
flash('大哥,又换签名了')
flash('常换签名,才能吸引眼球')
session['name'] = form.name.data
return redirect(url_for('index'))
name = session.get('name')
# 分配到模板中进行渲染
return render_template('form.html', form=form, name=name)
显示消息
{# 获取所有的flash消息,然后遍历显示 #}
{% for message in get_flashed_messages() %}
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{message}}
</div>
{% endfor %}
提示
若好多页面都有弹出消息,可以将flash消息放在基础模板中展示
6、Flask-Moment
说明
专门负责时间本地化显示的扩展库,使用非常方便
安装
pip install flask-moment
使用
向模板传递时间
# 导入类库
from flask_moment import Moment
from datetime import datetime, timedelta
# 创建对象
moment = Moment(app)
@app.route('/moment/')
def mom():
current_time = datetime.utcnow() + timedelta(seconds=-3600)
return render_template('moment.html', current_time=current_time)
模板中显示
{# 简单的格式化显示 #}
<div>时间:{{ moment(current_time).format('LLLL') }}</div>
<div>时间:{{ moment(current_time).format('LLL') }}</div>
<div>时间:{{ moment(current_time).format('LL') }}</div>
<div>时间:{{ moment(current_time).format('L') }}</div>
{# 自定义格式化显示 #}
<div>自定义显示:{{ moment(current_time).format('YYYY-MM-DD') }}</div>
{# 时间差值显示 #}
<div>发表于:{{ moment(current_time).fromNow() }}</div>
{# 加载jQuery,因为moment.js依赖,使用bootstrap时可以省略 #}
{{ moment.include_jquery() }}
{# 加载moment.js #}
{{ moment.include_moment() }}
{# 设置中文显示 #}
{{ moment.locale('zh-CN') }}
提示
格式化显示不要记忆,去官网查询即可
momentjs.com
6、Flask-Uploads
a.原生上传文件
b.模板文件
<html>
<head>
<title>原生文件上传</title>
</head>
<body>
{% if img_url %}
<img src="{{ img_url }}">
{% endif %}
<form method="post" enctype="multipart/form-data">
<input type="file" name="photo" />
<input type="submit" value="上传" />
</form>
</body>
</html>
c.视图函数
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
if request.method == 'POST':
file = request.files.get('photo')
if file and allowed_file(file.filename):
# 获取文件后缀
suffix = os.path.splitext(file.filename)[1]
# 生成随机文件名
filename = random_string() + suffix
# 保存上传文件
file.save(os.path.join(app.config['UPLOAD_FOLDER'],
filename))
# 构造上传的文件的访问URL
img_url = url_for('uploaded', filename=filename)
return render_template('upload.html', img_url=img_url)
相关配置
# 允许上传的文件后缀
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
# 配置上传文件保存位置
app.config['UPLOAD_FOLDER'] = os.getcwd()
# 上传文件大小
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8
支持函数
判断是否是允许的文件后缀
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
生成随机的字符串
def random_string(length=32):
import random
base_str = 'abcdefghijklmnopqrstuvwxyz1234567890'
return ''.join(random.choice(base_str) for i in range(length))
获取上传文件
@app.route('/uploaded/<filename>')
def uploaded(filename):
# 安全的发送文件
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
注意事项,文件上传失败时,应从哪些方面着手
1.表单的提交方法必须是POST
2.表单的enctype属性必须设置为multipart/form-data
3.上传的字段类型必须为file,并且必须有name属性
4.是否超过运行的最大尺寸
5.文件的保存位置是否有空间,是否有权限
生成缩略图
需要安装pillow库
# 导入图片处理的类,默认PIL不支持python3.x,安装pillow后就可以了
from PIL import Image
# 生成缩略图
# 1.打开文件
img = Image.open(pathname)
# 2.重设尺寸
img.thumbnail((128, 128))
# 3.保存修改
img.save(pathname)
flask-uploads
说明:在文件上传时,提供了很大的方便,如:文件类型的过滤,校验,文件保存,获取url等
安装:pip install flask-uploads
使用
相关配置
# 上传文件的大小
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8
# 上传文件的保存位置
app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd()
# 创建上传对象,指定过滤的文件后缀
photos = UploadSet('photos', IMAGES)
configure_uploads(app, photos)
# 配置上传文件大小,默认64M,
#设置为None时使用MAX_CONTENT_LENGTH选项
patch_request_class(app, size=None)
视图函数
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
if request.method == 'POST' and 'photo' in request.files:
# 保存文件
filename = photos.save(request.files['photo'])
# 获取保存文件的url
img_url = photos.url(filename)
return render_template('upload.html', img_url=img_url)
模板文件
同原生的文件上传upload.html
d.结合wtf做文件上传
flask-uploads配置同上
flask-wtf配置
# 导入表单基类
from flask_wtf import FlaskForm
# 导入文件上传字段及验证器
from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import SubmitField
# 上传文件表单类
class UploadForm(FlaskForm):
photo = FileField('头像上传', validators=[FileRequired('文件未选择'),
FileAllowed(photosUS, message='只能上传图片文件')])
submit = SubmitField('上传')
视图函数
@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
form = UploadForm()
if form.validate_on_submit():
# 获取文件后缀
suffix = os.path.splitext(form.photo.data.filename)[1]
# 生成所及文件名
filename = random_string() + suffix
# 保存上传文件
photos.save(form.photo.data, name=filename)
# 生成缩略图
pathname = os.path.join(app.config['UPLOADED_PHOTOS_DEST'],
filename)
# 打开文件
img = Image.open(pathname)
# 设置尺寸
img.thumbnail((128, 128))
# 保存文件
img.save(pathname)
# 获取上传文件的url
img_url = photos.url(filename)
return render_template('upload.html', form=form, img_url=img_url)
模板文件upload.html
{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block content %}
<div class="container">
{% if img_url %}
<img src="{{ img_url }}" />
{% endif %}
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
常用API
配置默认的上传文件大小:
app.config['MAX_CONTENT_LENGTH'] = 8 * 1024 *1024
配置图片格式的上传文件存储路径:
app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd()
定义一个图片格式的上传对象:
photos = UploadSet('photos', IMAGES)
保存上传对象到指定路径
filename = uploadSet.save(request.files['photo'])
filename = uploadSet.save(form.filefield.data, name=form.filefield.data.filename)
获得指定文件的访问url:
file_url = uploadSet.url(filename)
绑定app和uploadSet对象:configure_uploads(app, photos)
指定上传文件的大小:patch_request_class(app, size=6410241024)
allowed_file(file.filename)
suffix = os.path.splitext(file.filename)[1]
csrf校验:
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY','123456')
Bootstrap对象:
bootstrap = Bootstrap(app)
创建表单:
class UploadForm(FlaskForm):
文件对象:
photo = FileField('photo',validators=[FileRequired('必须选择文件'),FileAllowed(photos,'必须是图片类型')])
提交对象:
submit = SubmitField('UPLOAD')
表单校验:
if form.validate_on_submit():
pass
继承bootstrap:
{% extends 'bootstrap/base.html' %}
引入wtf:
{% import 'bootstrap/wtf.html' as wtf %}
快速集成表单:
{{ wtf.quick_form(form) }}
7、Flask-Login
初始化和配置
登录管理器对象:login_manager = LoginManager(app)
动态绑定app:login_manager.init_app(app)
登录重定向路由:login_manager.login_view = ‘user.login’
定义登录的路由函数
登录重定向信息:login_manager.login_message = ‘需要登录才可访问’
登录提示信息
设置session的保护级别:login_manager.session_protection = ‘strong’
basic=默认级别
strong=加强保护
None=禁用
配置用户模型
class User(UserMixin, db.Model):
登录认证的回调
@login_manager.user_loader
def load_user(uid):
return User.query.get(int(uid))
返回一个用户对象(以便存取用户状态)
使用
登录(记住我)
login_user(u, remember=form.remember.data)
获取当前登录用户
current_user
当前登录用户
是否已登录:current_user.is_authenticated
是否匿名:current_user.is_anonymous
u = current_user._get_current_object()
登出
logout_user()
路由保护
@app.route('/test/')
@login_required
def test():
return '登录后才可访问的页面'
【后记】:如果文章对您有帮助,打赏下呗。微信 1257309054,欢迎交流学习*_*
微信
支付宝