Python+Flask.0010.FLASK即插视图之自定义视图类及修饰器

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

即插视图;

说明: FLASK的视图灵感来自于DJANGO的基于类而非基于函数的通用视图,主要目的是为了解决多个视图函数之间已经实现的部分,通过类继承的方式继承到其它视图,总之为了一点,就是少写代码,然后通过add_url_rule让我们定义的视图类支持动态插入,也就是所谓的即插视图

 

深入视图:

# 转换前:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# 51CTOBG: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

from flask import Flask, render_template

# 说明: 导入其它模块

app = Flask(__name__)

@app.route('/about')

def web_about():

    return render_template('/web/about.html')

@app.route('/usr_manager')

def usr_manager():

    usrs = [u'李满满']

    return render_template('web/usr/manager.html', usrs=usrs)

@app.route('/grp_manager')

def grp_managr():

    grps = [u'管理员']

    return render_template('web/grp/manager.html', grps=grps)

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=9000, debug=True)

说明: 如上三个视图函数代码基本类似,都是获取数据渲染模版或直接渲染模版,我们可以尝试通过即插视图子类继承来让适应于更多的模型和模版,更加的灵活,首先得转换为类视图

# 转换后:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# 51CTOBG: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

from flask import Flask, render_template, jsonify

from flask.views import View

# 说明: 导入其它模块

app = Flask(__name__)

class BaseView(View):

    def __init__(self, template_name):

        self.template_name = template_name

    def get_objects(self):

        return {}

    def render_template(self, context):

        return render_template(self.template_name, **context)

    def dispatch_request(self):

        context = {'objects'self.get_objects()}

        return self.render_template(context)

class UsrManager(BaseView):

    def get_objects(self):

        return [u'李满满']

class GrpManager(BaseView):

    def get_objects(self):

        return [u'管理员']

app = Flask(__name__)

app.add_url_rule('/about', view_func=BaseView.as_view('web_about', template_name='web/about.html'))

app.add_url_rule('/web/usr/manager', view_func=UsrManager.as_view('usr_manager', template_name='web/usr/manager.html'))

app.add_url_rule('/web/grp/manager', view_func=GrpManager.as_view('grp_manager', template_name='web/grp/manager.html'))

@app.route('/')

def index():

    return jsonify({'all_url_map': app.url_map.__str__()})

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=9000, debug=True)

说明: 使用基于类的即插视图首先得声明一个继承自flask.views.View的子类,且必须实现一个dispatch_request调度请求的方法,在调度请求中返回原始响应数据即可,如果要将其加入app.url_map表中需要通过app.add_url_rule(self, *args, **kwargs)方法将URL规则与视图函数绑定, 既然绑定的是视图函数,那肯定不能直接绑定子类,基类flask.views.View为我们提供了一个.as_view(name, *args, **kwargs)类方法,继承下来我们可以直接调用生成一个名字为name的视图函数,当请求符合URL规则时会通过转换器将to_python数据按照app.url_map传递给对应的视图函数来处理,视图函数有可能是被装饰的函数,也有可能是通过即插视图生成的函数,最终返回的结果在在响应装饰器中修饰以便最终返回给客户端

扩展: 如果想限制HTTP方法,可以直接在基类BaseView或是子类中声明类属性methods=['GET', 'POST']或是指定单GET/POST协议即可,如果希望对于GET/POST协议做单独处理,只需要基类继承flask.views.MethodView然后在子类中实现get/post方法,然后就可以不提供methods类属性,它会自动的按照子类中的定义去处理GET或是POST请求

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# 51CTOBG: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

from flask import Flask, render_template, jsonify, request

from flask.views import MethodView

# 说明: 导入其它模块

app = Flask(__name__)

class BaseView(MethodView):

    def __init__(self, template_name):

        self.template_name = template_name

    def render_template(self, context):

        return render_template(self.template_name, **context)

    def dispatch_request(self):

        objects = getattr(self, request.method.lower())()

        context = {'objects': objects}

        return self.render_template(context)

class UsrManager(BaseView):

    def get(self):

        return [u'李满满']

    def post(self):

        return [u'刘珍珍']

class GrpManager(BaseView, MethodView):

    def get(self):

        return [u'匿名者']

    def post(self):

        return [u'管理员']

app = Flask(__name__)

app.add_url_rule('/about', view_func=BaseView.as_view('web_about', template_name='web/about.html'))

app.add_url_rule('/web/usr/manager', view_func=UsrManager.as_view('usr_manager', template_name='web/usr/manager.html'))

app.add_url_rule('/web/grp/manager', view_func=GrpManager.as_view('grp_manager', template_name='web/grp/manager.html'))

@app.route('/')

def index():

    return jsonify(help(app.add_url_rule))

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=9000, debug=True)

扩展: FLASK还支持在运行视图函数之前通过装饰器的方式来实现权限检查,登录验证等操作,由于视图类最终是通过.as_view生成视图函数,所以基于视图类添加修饰器无卵用,只能在.as_view上做,新版的直接支持基类属性decorators列表,定义装饰器列表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

#!/usr/bin/env python

# -*- coding: utf-8 -*-

"""

#

# Authors: limanman

# 51CTOBG: http://xmdevops.blog.51cto.com/

# Purpose:

#

"""

# 说明: 导入公共模块

from flask import Flask, render_template, jsonify, request, session, abort

from flask.views import MethodView

# 说明: 导入其它模块

app = Flask(__name__)

def user_required(func):

    def wrapper(*args, **kwargs):

        uid = session.get('id'None)

        if not uid:

            abort(401)

        return func(*args, **kwargs)

    return wrapper

class BaseView(MethodView):

    decorators = [user_required]

    def __init__(self, template_name):

        self.template_name = template_name

    def render_template(self, context):

        return render_template(self.template_name, **context)

    def dispatch_request(self):

        objects = getattr(self, request.method.lower())()

        context = {'objects': objects}

        return self.render_template(context)

class UsrManager(BaseView):

    def get(self):

        return [u'李满满']

    def post(self):

        return [u'刘珍珍']

class GrpManager(BaseView, MethodView):

    def get(self):

        return [u'匿名者']

    def post(self):

        return [u'管理员']

app = Flask(__name__)

app.add_url_rule('/about', view_func=BaseView.as_view('web_about', template_name='web/about.html'))

app.add_url_rule('/web/usr/manager', view_func=UsrManager.as_view('usr_manager', template_name='web/usr/manager.html'))

app.add_url_rule('/web/grp/manager', view_func=GrpManager.as_view('grp_manager', template_name='web/grp/manager.html'))

@app.route('/')

def index():

    return jsonify(help(app.add_url_rule))

if __name__ == '__main__':

    app.run(host='0.0.0.0', port=9000, debug=True)

说明: FLASK为我们提供了decorators类属性来设置装饰器列表,当然其实也可以手动的在app.add_url_rule之前来修饰view_func = user_required(BaseView.as_view('web_about', template_name='web/about.html')),此时view_func就已被修饰,添加了验证功能

 

登录乐搏学院官网http://www.learnbo.com/

或关注我们的官方微博微信,还有更多惊喜哦~

 

本文出自 “满满李 - 运维开发之路” 博客,请务必保留此出处http://xmdevops.blog.51cto.com/11144840/1866526

转载于:https://my.oschina.net/learnbo/blog/863217

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InputStream和Reader,FileInputStream和 FileReader的区别

一、InputStream和Reader的区别 InputStream和Reader都可以用来读数据(从文件中读取数据或从Socket中读取数据),最主要的区别如下: InputStream用来读取二进制数(字节流),而 Reader用来读取文本数据,即 Unicode字符。那么二进制数与文本数据有…

NGUI之输入文本框的使用

ToolBar中的两个红圈 另,代码如下:只需要定义一个变量即可,然后将控件drag到那里,真的是灰常方便呀 还有一个就是保存了(OK的响应),可以简单地理解为存档或读档 转载于:https://www.cnblogs.com/YTYMblog/p…

tensorrt轻松部署高性能dnn推理_实战教程:TensorRT中递归神经网络的介绍(中文字幕)...

NVIDIA TensorRT是一个高性能的深度学习推理优化器和运行时,它提供低延迟和高吞吐量。TensorRT可以从每个深度学习框架导入经过训练的模型,从而轻松地创建可以集成到大型应用程序和服务中的高效推理引擎。这个视频的五个关键点:1.TensorRT支持RNNv2, Mat…

w怎么接显示 树莓派zero_纯干货!一根线玩转树莓派ZeroW(图文教程,亲测有效)...

#一、写在前面本文旨在介绍如何用最少的外设(成本)完成树莓派Zero W最基础最重要的功能。注意:本文原始发表时官方镜像版本是2017-04-10的,在2019年5月10日有网友提出本方案已经不完全适用最新的镜像了,所以如果只是想按照本文所提出的步骤一…

十进制小数转换二进制的问题

2019独角兽企业重金招聘Python工程师标准>>> 整数和小数分别转换。 整数除以2,商继续除以2,得到0为止,将余数逆序排列。 22 / 2 11 余0 11/2 5 余 1 5 /2 2 余 1 2 /2 1 余 0 1 /2 0 余 1 所以22的二进制…

java操作mongodb(连接池)(转)

原文链接: java操作mongodb(连接池) Mongo的实例其实就是一个数据库连接池,这个连接池里默认有10个链接。我们没有必要重新实现这个链接池,但是我们可以更改这个连接池的配置。因为Mongo的实例就是一个连接池&#xff…

声卡突然听不到监听_音乐人/键盘手伴侣物问题之:专业监听音箱的音质必须用独立声卡...

近日,不少朋友在后台留言,询问专业监听音箱连电脑听音乐要不要接个声卡!本期我们针对此问题,跟大家分享一些心得与经验。先回答问题,当然要!通常我们电脑上的音频输出口是这样的:而专业监听音箱…

helm3安装mysql_Helm3(kubernetes包管理工具)安装使用踩坑指南

image.png从结构中我们看到有不同级别的文件夹,以及一些yaml文件。charts: 用于存放其他依赖和关联的chart。例如应用依赖数据库的chart。Chart.yaml:存储一些元数据,例如chart的信息,描述等等templates文件夹&#xf…

Redis-3.2主从复制与集群搭建 推荐

Redis-3.2主从复制与集群搭建 一、Redis 主从搭建 1.下载并解压 yum install -y gcc gcc-c pcre zlib pcre-devel tcl wget http://download.redis.io/releases/redis-3.2.4.tar.gz tar -zxvf redis-3.2.4.tar.gz cd redis-3.2.4 make cd src && make test &&am…

苹果手机输入屏保后锁屏_修一块手机屏幕要7080元?

这几天华为Mate X的两次开售成为大家议论的话题,一些抢到的人自然沉浸在快乐之中,想着是自己留着用,还是转手赚一把。而一些想抢而没抢到的人或许正在研究如何在明天的第三次开售中抓好机会吧!当然,也有像小编这样的&a…

中间介(MiddleWare)

引子-Django的生命周期 在学习中间介之前,我们先来回顾一下Django的生命周期:用户发起请求,请求会被发送到urlconf中的url,然后会指向对应的views函数进行处理,views函数处理完成后,用模板渲染好html&#…

对MariaDB10.0的Sphinx进行扩展

已修改过的文件:http://pan.baidu.com/s/1o8DHvkA 将这两个文件放到MariaDB的解压目录后,再进行安装 /usr/local/mariadb-10.0.28/storage/sphinx/ 如下是修改的代码 get_rec ( byte * buf, const byte * key, uint keylen,uint a,uint b,uint c );index…

容器created状态_docker容器状态的转换实现

一 docker容器状态转换图二 实战[rootlocalhost ~]# docker infoContainers: 0Running: 0Paused: 0Stopped: 0Images: 3Server Version: 17.09.0-ceStorage Driver: overlayBacking Filesystem: xfsSupports d_type: falseLogging Driver: json-fileCgroup Driver: cgroupfsPlu…

ubuntu16.04配置sonarqube+MySQL

环境:rootubuntu:~# uname -a Linux ubuntu 4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux rootubuntu:~# rootubuntu:~# cat /etc/issue Ubuntu 16.04 LTS \n \lrootubuntu:~#安装配置mysql:1、更新源…

鼠标固定在屏幕中间_无线电竞黑科技,雷柏VT950Q游戏鼠标评测

雷柏作为目前小有声誉的PC外设品牌,其定位高性能游戏领域的VT系列产品,想必大家也比较熟悉了。VT系列的产品除了有超强的性能以及出色的设计感,同时还都是性价比非常高的产品,即便是采用了旗舰级传感器,定位最为高端的…

WebSnapshotsHelper(HTML转换为图片)

1 /// <summary>2 /// WebBrowser Url生成图片3 /// HTML转图片4 /// </summary>5 public class WebSnapshotsHelper6 {7 Bitmap m_Bitmap;8 string m_Url;9 int m_BrowserWidth, m_BrowserHeight, m_ThumbnailWidth,…

synchronized 和 reentrantlock 区别是什么_JUC源码系列之ReentrantLock源码解析

目录ReentrantLock 简介ReentrantLock 使用示例ReentrantLock 与 synchronized 的区别ReentrantLock 实现原理ReentrantLock 源码解析ReentrantLock 简介ReentrantLock 是 JDK 提供的一个可重入的独占锁&#xff0c;独占锁&#xff1a;同一时间只有一个线程可以持有锁可重入&am…

mysql8.0递归_mysql8.0版本递归查询

1.先在mysql数据库添加数据DROP TABLE IF EXISTS dept;CREATE TABLE dept (id int(11) NOT NULL,pid int(11) DEFAULT NULL,name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,date datetime(0) DEFAULT NULL,PRIMARY KEY (id) USING BTREE) ENGINE…

计算机中的字符编码

字符编码 什么是计算机编码 计算机只能处理二进制的数据&#xff0c;其它的数据都要进行转换&#xff0c;但转换必须要有一套字符编码(是字符与二进制的一个对应关系)。常用的字符&#xff1a;a-z、0-9、其它的符号等&#xff0c;计算机也不能直接处理。 &#xff08;字符编码类…

应急照明市电检测_应急照明如何供电? 如何接线? 图文分析!

对于大部分刚接触建筑电气设计的工作者来说&#xff0c;应急照明的强启原理一直都是很头疼的问题。由于不知道应急照明的强启原理&#xff0c;所以&#xff0c;应急灯具应该用多少根线&#xff0c;其实也就无从谈起。下面以文字和图片结合的方式来说明应急灯怎么接线的&#xf…