Flask(10)- 标准类视图
前言
- 前面文章讲解 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',
}
app.py 应用主入口
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/13 10:31 下午
# file: 8_app.py
""" from flask import Flask, views from s8_userview import UserView app = Flask(__name__) app.add_url_rule('/user/', view_func=UserView.as_view('UserView'))
app.run(debug=True)
user.html 代码
<html>
<body>
<h2>name = {{ name }}</h2>
<h2>gender = {{ gender }}</h2>
</body>
</html>
浏览器访问的效果

使用装饰器
在视图函数、视图类中使用装饰器还是一大杀器
检查登录功能
不使用装饰器前的代码
def check_login():
if 用户已经登录:
return True
else:
return False @app.route('/page1', page1)
def page1():
if not check_login():
return '请先登录'
执行 page1 的功能 @app.route('/page2', page2)
def page2():
if not check_login():
return '请先登录'
执行 page2 的功能
- 在处理 /page1 和 /page2 时需要检查登录,在函数 page1 () 和 page2 () 的头部调用 check_login 函数
- 这种方法虽然实现了功能,但不够简洁
检查登录的装饰器
使用装饰器实现登录的功能,定义检查登录的装饰器 check_login
from flask import request from functools import wraps def check_login(original_function):
@wraps(original_function)
def decorated_function(*args, **kwargs):
user = request.args.get("user")
if user and user == "zhangsan":
return original_function(*args, **kwargs)
else:
return "请登录" return decorated_function()
- 装饰器 check_login 本质是一个函数
- 它的输入是一个函数 original_function
- 它的输出也是一个函数 decorated_function
- original_function 是原先的处理 URL 的视图函数,它不包含检查登录的功能逻辑,就是到时候需要添加装饰器的函数
- decorated_function 是在 original_function 的基础上进行功能扩充的函数(这就是装饰器的功能),它首先检查是否已经登录,如果已经登录则调用 original_function,如果没有登录则返回错误
- 使用 functools.wraps (original_function) 保留原始函数 original_function 的属性
在视图函数中使用装饰器
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/13 10:31 下午
# file: 8_app.py
""" from flask import Flask, request
from functools import wraps app = Flask(__name__) # 定义装饰器
def check_login(original_function):
@wraps(original_function)
def decorated_function(*args, **kwargs):
user = request.args.get("user")
if user and user == "zhangsan":
return original_function(*args, **kwargs)
else:
return "请登录" return decorated_function() @app.route("/page1")
@check_login
def page1():
return "page1" @app.route("/page2")
@check_login
def page2():
return "page2" app.run(debug=True)
- page1、page2 两个视图函数更关注请求处理,而检查登录的功能交给装饰器去负责
- 这样,检查登录的功能与 page1 和 page2 本身的功能是分离的
浏览器访问的效果



在视图类中使用装饰器
#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
# author: 小菠萝测试笔记
# blog: https://www.cnblogs.com/poloyy/
# time: 2021/7/13 11:06 下午
# file: 8_viewclass_decorated.py
""" from flask import Flask, request, views
from functools import wraps app = Flask(__name__) def check_login(original_function):
@wraps(original_function)
def decorated_function(*args, **kwargs):
user = request.args.get("user")
if user and user == 'zhangsan':
return original_function(*args, **kwargs)
else:
return '请先登录' return decorated_function class Page1(views.View):
decorators = [check_login] def dispatch_request(self):
return 'Page1' class Page2(views.View):
decorators = [check_login] def dispatch_request(self):
return 'Page2' app.add_url_rule(rule='/page1', view_func=Page1.as_view('Page1'))
app.add_url_rule(rule='/page2', view_func=Page2.as_view('Page2'))
app.run(debug=True)
decorators = [check_login] 设定视图类的装饰器
Flask(10)- 标准类视图的更多相关文章
- Flask初学者:视图函数和类视图
当一个url请求进入后台时,一般有两种方式来进行处理:视图函数和类视图.视图函数直接使用一个函数来进行处理并返回数据给浏览器,类视图则是使用类来进行处理并返回的,所以当需要进行的处理比较简单,则可以考 ...
- 9、Flask实战第9天:类视图
之前我们接触的视图都是函数,所以一般简称为视图函数.其实视图函数也可以基于类来实现,类视图的好处是支持继承,写完类视图需要通过app.add_url_rule(url_rule, view_func) ...
- Dajngo——10 请求与响应 文件上传 GET和POST请求 类视图
Dajngo——10 HttpRequest对象 HttpResponse对象及子类 form标签中的GET和POST GET提交方式 POST提交方式 request得GET和POST属性 文件上传 ...
- 10、Flask实战第10天:视图使用装饰器
在实际开发中,我们有时候会用到自己定义装饰器并应用到函数视图或者类视图里面:比如:我们要想进入个人中心页面,首先要验证你是否登录,否则进不去,下面我们来模拟这个场景 定义一个装饰器 from func ...
- python框架之Flask(2)-路由和视图&Session
路由和视图 这一波主要是通过看源码加深对 Flask 中路由和视图的了解,可以先回顾一下装饰器的知识:[装饰器函数与进阶] 路由设置的两种方式 # 示例代码 from flask import Fla ...
- flask之URL和视图(一)
1.Flask URL和视图 1.1.第一个flask程序 from flask import Flask #创建一个Flask对象,传递__name__参数进去 app = Flask(__name ...
- Flask05 cookie、类视图、方法视图、自己的404页面
1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我 你要先登录(用户名.密码) -> ...
- C# 语言规范_版本5.0 (第10章 类)
1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...
- Django学习笔记之视图高级-类视图
类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...
随机推荐
- flink的checkpoint页面监控
flink web页面中提供了针对Job Checkpoint相关的监控信息.Checkpoint监控页面共有overview.history.summary和configuration四个页签,分别 ...
- 1130-host ... is not allowed to connect to this MySql server
解决方法: 1. 改表法. 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 ...
- UnicodeDecodeError:'ascii' codec can't decode byte 0xe5 in position 89: ordinal not in range(128)
环境python2,在出现该错误的python文件,增加: import sys reload(sys) sys.setdefaultencoding('utf8') 重新运行,不再报错
- Go语言web开发---Beego路由
参考链接(查看更多):https://beego.me/docs/mvc/controller/router.md 基础路由 从 beego 1.2 版本开始支持了基本的 RESTful 函数式路由, ...
- TensorFlow实现超参数调整
TensorFlow实现超参数调整 正如你目前所看到的,神经网络的性能非常依赖超参数.因此,了解这些参数如何影响网络变得至关重要. 常见的超参数是学习率.正则化器.正则化系数.隐藏层的维数.初始权重值 ...
- ES6中的数组常用方法
数组在JS中虽然没有函数地位那么高,但是也有着举足轻重的地位,下面我就结合这ES5中的一些常用的方法,与ES6中的一些方法做一些说明和实际用途.大家也可以关注我的微信公众号,蜗牛全栈. 一.ES5中数 ...
- 【NX二次开发】获取指定矩阵标识的矩阵值
函数:UF_CSYS_ask_matrix_values () 函数说明:获取指定矩阵标识的矩阵值. 用法: #include <uf.h> #include <uf_csys.h& ...
- 【C++】枚举类型(enum )
定义枚举类型的主要目的是:增加程序的可读性.枚举类型最常见也最有意义的用处之一就是用来描述状态量.枚举类型数据的其他处理也往往应用switch语句,以保证程序的合法性和可读性.枚举值是常量不是变量,不 ...
- NOIP模拟测试20「周·任·飞」
liu_runda出的题再次$\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%$ 任 题解 题目中为什么反复强调简单路径,没有环 没有环的图中点数-边数=联通块数 前缀和维护边 ...
- Shiro-JWT SpringBoot前后端分离权限认证的一种思路
JWT-Shiro 整合 JWT-与Shiro整合进行授权认证的大致思路 图示 大致思路 将登录验证从shiro中分离,自己结合JWT实现 用户登陆后请求认证服务器进行密码等身份信息确认,确认成功后 ...