前言

  • 前面文章讲解 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 。使用视图类的步骤如下:

  1. 用户定义一个视图类,继承于 Flask.views.View;
  2. 在视图类中定义方法 dispatch_request ,处理请求、返回 HTML 文本给客户端;
  3. 使用 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()
  1. 定义了一个静态方法 as_view,它首先创建一个实例 view
  2. 然后返回实例 view 的 dispatch_request 方法
  3. 即 view_func 指向了实例 view 的方法 dispatch_request
  4. 当访问页面路径 / 时,最终会调用 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)- 标准类视图的更多相关文章

  1. Flask初学者:视图函数和类视图

    当一个url请求进入后台时,一般有两种方式来进行处理:视图函数和类视图.视图函数直接使用一个函数来进行处理并返回数据给浏览器,类视图则是使用类来进行处理并返回的,所以当需要进行的处理比较简单,则可以考 ...

  2. 9、Flask实战第9天:类视图

    之前我们接触的视图都是函数,所以一般简称为视图函数.其实视图函数也可以基于类来实现,类视图的好处是支持继承,写完类视图需要通过app.add_url_rule(url_rule, view_func) ...

  3. Dajngo——10 请求与响应 文件上传 GET和POST请求 类视图

    Dajngo——10 HttpRequest对象 HttpResponse对象及子类 form标签中的GET和POST GET提交方式 POST提交方式 request得GET和POST属性 文件上传 ...

  4. 10、Flask实战第10天:视图使用装饰器

    在实际开发中,我们有时候会用到自己定义装饰器并应用到函数视图或者类视图里面:比如:我们要想进入个人中心页面,首先要验证你是否登录,否则进不去,下面我们来模拟这个场景 定义一个装饰器 from func ...

  5. python框架之Flask(2)-路由和视图&Session

    路由和视图 这一波主要是通过看源码加深对 Flask 中路由和视图的了解,可以先回顾一下装饰器的知识:[装饰器函数与进阶] 路由设置的两种方式 # 示例代码 from flask import Fla ...

  6. flask之URL和视图(一)

    1.Flask URL和视图 1.1.第一个flask程序 from flask import Flask #创建一个Flask对象,传递__name__参数进去 app = Flask(__name ...

  7. Flask05 cookie、类视图、方法视图、自己的404页面

    1 什么是cookie 就是网站存放到你浏览器中的一部分固定内容:当你下次访问我这个网站的时候,你会把之前我存放到你浏览器中的数据带回来给我        你要先登录(用户名.密码) ->   ...

  8. C# 语言规范_版本5.0 (第10章 类)

    1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...

  9. Django学习笔记之视图高级-类视图

    类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...

随机推荐

  1. SystemVerilog MCDF检测器

    Monitor:检测DUT的边界信号或者内部信号,并且经过打包整理传送给其他的验证平台的组件(例如checker). 一:大的monitor方案 二:分布式的 两个monitor的比较: 比较下来,选 ...

  2. Docker环境下运行python+selenium+chrome

    Docker环境下运行python+selenium+chrome docker运行时占用的资源非常少,而且能将环境进行有效的隔离,可以快速的进行部署,因此可以将docker与selenium结合实现 ...

  3. Docker学习(11) Dockerfile指令

    Dockerfile指令 指令格式 FROM MAINTAINER RUN EXPOSE CMD ENTRYPOINT ADD COPY VOLUME WORKDIR ENV USER ONBUILD ...

  4. 机器学习PAL数据预处理

    机器学习PAL数据预处理 本文介绍如何对原始数据进行数据预处理,得到模型训练集和模型预测集. 前提条件 完成数据准备,详情请参见准备数据. 操作步骤 登录PAI控制台. 在左侧导航栏,选择模型开发和训 ...

  5. OpenCV读写视频文件解析(二)

    OpenCV读写视频文件解析(二) VideoCapture::set 设置视频捕获中的属性. C++:bool VideoCapture::set(int propId, double value) ...

  6. TorchScript神经网络集成技术

    TorchScript神经网络集成技术 create_torchscript_neuropod 将TorchScript模型打包为neuropod包. create_torchscript_neuro ...

  7. springboot 集成 elk 日志收集功能

    Lilishop 技术栈 官方公众号 & 开源不易,如有帮助请点Star 介绍 官网:https://pickmall.cn Lilishop 是一款Java开发,基于SpringBoot研发 ...

  8. ubuntu虚拟机安装ssh教程

    大家好,这期给大家带来一期Ubuntu虚拟机中ssh的安装教程,话不多说,开整 第一步:输入su后输入密码进入root权限 第二步:在管理员模式下运行apt-get install openssh-s ...

  9. Python小白的数学建模课-06 固定费用问题

    Python 实例介绍固定费用问题的建模与求解. 学习 PuLP工具包中处理复杂问题的快捷使用方式. 『Python小白的数学建模课 @ Youcans』带你从数模小白成为国赛达人. 前文讲到几种典型 ...

  10. 停车场事故频频,AI 达人将摄像头变身安全卫士

    2021 年 2 月,"新内容 新交互" 全球视频云创新挑战赛启幕.本次大赛由英特尔联合阿里云主办,与优酷战略技术合作,天池平台和阿里云视频云团队共同承办.大赛自开赛以来,吸引了全 ...