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_filenameapp = Flask(__name__)def auth(func):def inner(*args, **kwargs):res = func(*args, **kwargs)print('已走装饰器')return resreturn innerclass 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):@authdef get(self):return 'Hello GET'
闪现(Flash)
目的:用于在请求之间传递一次性消息
实现方式:基于Flask的会话(session)对象实现,但比普通会话对象更加灵活和轻量级
特点:设置消息后,在下一个请求中检索并显示,然后自动删除
在Django中有和flash类似的中间件:message
示例
使用闪现必须配置app.secret_key
get_flashed_messages
获取全部闪现数据
from flask import Flask, flash, get_flashed_messagesapp = Flask(__name__)
app.secret_key = 'abcd'@app.route('/')
def home():flash('闪现')return '已经添加闪现'@app.route('/index')
def index():msg = get_flashed_messages()if msg:return msgreturn '没有查找到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, gapp = 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 widgetsapp = Flask(__name__, template_folder='templates')app.debug = Trueclass 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()