前言
- 前面文章讲解 Flask 路由的时候,都是将 URL 路径和一个视图函数关联
- 当 Flask 框架接收到请求后,会根据请求 URL,调用响应的视图函数进行处理
- Flask 不仅提供了视图函数来处理请求,还提供了视图类;可以将 URL 路径和一个视图类关联
标准视图函数
- 将 URL 路径和一个函数关联,这个函数又被称为视图函数,Flask 框架会根据请求的 URL 调用相应的视图函数进行处理
- 当访问 127.0.0.1:5000/ 时,index() 函数就会处理该请求,并返回 hello world 字符串
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'hello world' app.run(debug = True)
标准视图类
Flask.views.View 是 Flask 的标准视图类,用户定义的视图类需要继承于 Flask.views.View 。使用视图类的步骤如下:
- 用户定义一个视图类,继承于 Flask.views.View;
- 在视图类中定义方法 dispatch_request ,处理请求、返回 HTML 文本给客户端;
- 使用 app.add_url_rule (rule, view_func) 将 URL 路径和视图类绑定
最简单的栗子
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/13 8:42 下午 # file: 8_view_class.py """ from flask import Flask, views from flask.typing import ResponseReturnValue app = Flask(__name__) # 自定义视图类,继承 views.View class view_test(views.View): # 返回一个字符串给客户端 def dispatch_request(self) -> ResponseReturnValue: return "hello world" # 将路由规则 / 和视图类 view_test 进行绑定 app.add_url_rule(rule="/", view_func=view_test.as_view("view")) if __name__ == '__main__': app.run()
重点 as_view
- view_test.as_view("view") 代表创建了一个名称为 view 的视图函数
- app.add_url_rule 实际上是将路由规则和视图函数(由视图类的 as_view 方法转换而来)绑定
浏览器访问的效果
as_view 函数
视图类的本质是视图函数,函数 View.as_view () 会返回一个视图函数
简化版
为了更清晰理解 as_view 函数的功能,自行实现一个简化版本的 as_view 函数
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/13 8:42 下午 # file: 8_view_class.py """ from flask import Flask, views from flask.typing import ResponseReturnValue app = Flask(__name__) class view_test2(views.View): def dispatch_request(self) -> ResponseReturnValue: return {"msg": "success", "code": 0} @staticmethod def as_view(name, **kwargs): view = view_test2() return view.dispatch_request # 将路由规则 / 和视图类 view_test 进行绑定 app.add_url_rule(rule="/", view_func=view_test2.as_view("view")) if __name__ == '__main__': app.run()
- 定义了一个静态方法 as_view,它首先创建一个实例 view
- 然后返回实例 view 的 dispatch_request 方法
- 即 view_func 指向了实例 view 的方法 dispatch_request
- 当访问页面路径 / 时,最终会调用 index.dispatch_request ()
继承
使用类视图的好处是支持继承,可以把一些共性的东西放在父类中,其他子类可以继承
父类 baseview
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/13 10:15 下午 # file: s8_baseview.py """ from flask import Flask, views, render_template app = Flask(__name__) class BaseView(views.View): # 如果子类忘记定义 get_template 就会报错 def get_template(self): raise NotImplementedError() # 如果子类忘记定义 get_data 就会报错 def get_data(self): raise NotImplementedError() def dispatch_request(self): # 获取模板需要的数据 data = self.get_data() # 获取模板文件路径 template = self.get_template() # 渲染模板文件 return render_template(template, **data)
子类 userview
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/7/13 10:15 下午 # file: 8_userview.py """ from s8_baseview import BaseView class UserView(BaseView): def get_template(self): return "user.html" def get_data(self): return { 'name': 'zhangsan', 'gender': 'male', }