Flask快速入门
目录
- Flask快速入门
- 请求扩展
- before_request
- after_request
- teardown_request
- errorhandler
- CBV加装饰器
- 闪现(Flash)
- 示例
- g对象
- 蓝图(blueprint)
- wtforms
请求扩展
常用的请求扩展:
before_request
after_request
teardown_request
errorhandler
before_request
在请求进入视图函数之前执行
@app.route('/')
def home():
print('home')
return 'home'
@app.before_request
def before01():
print('我是before_request')
控制台输出:
after_request
在执行完视图函数后会执行
@app.route('/')
def home():
print('home')
return 'home'
@app.after_request
def after01(response):
print('我是after_request')
return response
控制台打印:
teardown_request
无论视图代码执行成功或失败都会走teardown_request
,即使出现异常也会,一般用来记录日志
@app.teardown_request
def teardown(exc):
if exc:
print(f'出现异常:{exc}')
else:
print('请求成功结束或没有异常。')
errorhandler
当视图出现异常时会走errorhandler
,并捕获error信息
from flask import Flask, jsonify, abort
@app.errorhandler(404)
def error_404(err):
print('出现了404报错')
print(f'err:{err}')
return jsonify({'error': 'Not Found', 'code': '404'}), 404
@app.route('/notfound')
def not_found():
# 这里我们故意触发一个 404 错误
abort(404)
页面返回数据:
控制台输出:
CBV加装饰器
from flask import Flask, url_for, render_template, request, make_response, session, redirect
from flask.views import MethodView
from werkzeug.utils import secure_filename
app = Flask(__name__)
def auth(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
print('已走装饰器')
return res
return inner
class IndexView(MethodView):
# 装饰器列表
decorators = [auth]
# 指定当前视图类允许的请求方式
methods = ['GET', 'POST']
def get(self):
return 'Hello GET'
app.add_url_rule('/', view_func=IndexView.as_view('index'))
if __name__ == '__main__':
app.run(debug=True)
- 注意:该装饰器是非公用的,即要么给CBV使用要么给FBV使用,因为CBV首参数是self
除了decorators
方式也可以直接用@auth
class IndexView(MethodView):
@auth
def get(self):
return 'Hello GET'
闪现(Flash)
目的:用于在请求之间传递一次性消息
实现方式:基于Flask的会话(session)对象实现,但比普通会话对象更加灵活和轻量级
特点:设置消息后,在下一个请求中检索并显示,然后自动删除
在Django中有和flash类似的中间件:message
示例
使用闪现必须配置app.secret_key
get_flashed_messages
获取全部闪现数据
from flask import Flask, flash, get_flashed_messages
app = Flask(__name__)
app.secret_key = 'abcd'
@app.route('/')
def home():
flash('闪现')
return '已经添加闪现'
@app.route('/index')
def index():
msg = get_flashed_messages()
if msg:
return msg
return '没有查找到flash'
if __name__ == '__main__':
app.run(debug=True)
先访问http://127.0.0.1:5000
再访问http://127.0.0.1:5000/index
获取到闪现数据
如果再次访问index则会返回:
g对象
g对象就是global的缩写,它是一个特殊对象,用于在请求之间存储和传递数据
注意:一般我们不会把g对象放入request对象中,会造成数据污染
from flask import Flask, g
app = Flask(__name__)
@app.before_request
def before():
g.name = '张三'
@app.route('/')
def index():
print(g.name)
return 'home'
控制台输出:
张三
蓝图(blueprint)
Flask中的蓝图(Blueprint)是一个非常重要的概念,它提供了一种组织和管理路由、视图函数、错误处理程序以及静态文件的方法
from flask import Flask, g, Blueprint
app = Flask(__name__)
# 第一个参数是蓝图名
bp = Blueprint('demo1', __name__)
bp2 = Blueprint('demo2', __name__)
# 为bp蓝图定义路由和视图函数
@bp.route('/')
def demo1_index():
return 'Home from demo1'
# 为bp2蓝图定义路由和视图函数,注意这里使用了不同的函数名和URL路径
@bp2.route('/bp')
def demo2_index():
return 'Home from demo2'
# 在app中注册蓝图实例bp和bp2
app.register_blueprint(bp)
app.register_blueprint(bp2)
if __name__ == '__main__':
app.run(debug=True)
此时访问http://127.0.0.1:5000/bp
和http://127.0.0.1:5000
都能正常返回,但实际上它俩可以算作两个分支
注意:蓝图实例也可以使用请求扩展,一般只有大型项目才会使用蓝图
wtforms
-
WTForms提供了一个简单的接口来定义表单字段和验证规则,并将它们呈现为HTML表单。
-
它支持多种Web框架,如Flask、Django和Pyramid,使得在Web应用程序中使用表单变得简单方便。
-
核心功能
-
创建和定义表单字段:WTForms允许用户定义各种类型的表单字段,如文本字段、密码字段、单选按钮、复选框等。
from flask import Flask, render_template, request, redirect
from wtforms import Form
from wtforms.fields import simple
from wtforms import validators
from wtforms import widgets
app = Flask(__name__, template_folder='templates')
app.debug = True
class LoginForm(Form):
# 字段(内部包含正则表达式)
name = simple.StringField(
label='用户名',
validators=[
validators.DataRequired(message='用户名不能为空.'),
validators.Length(min=6, max=18, message='用户名长度必须大于%(min)d且小于%(max)d')
],
widget=widgets.TextInput(), # 页面上显示的插件
render_kw={'class': 'form-control'}
)
# 字段(内部包含正则表达式)
pwd = simple.PasswordField(
label='密码',
validators=[
validators.DataRequired(message='密码不能为空.'),
validators.Length(min=8, message='用户名长度必须大于%(min)d'),
validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')
],
widget=widgets.PasswordInput(),
render_kw={'class': 'form-control'}
)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
form = LoginForm()
return render_template('login.html', form=form)
else:
form = LoginForm(formdata=request.form)
if form.validate():
print('用户提交数据通过格式验证,提交的值为:', form.data)
else:
print(form.errors)
return render_template('login.html', form=form)
if __name__ == '__main__':
app.run()
ml’, form=form)
else:
form = LoginForm(formdata=request.form)
if form.validate():
print(‘用户提交数据通过格式验证,提交的值为:’, form.data)
else:
print(form.errors)
return render_template(‘login.html’, form=form)
if name == ‘main’:
app.run()