博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python+Flask.0010.FLASK即插视图之自定义视图类及修饰器
阅读量:6247 次
发布时间:2019-06-22

本文共 6333 字,大约阅读时间需要 21 分钟。

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__)

.route('/about')

def web_about():

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

.route('/usr_manager')

def usr_manager():

    usrs = [u'李满满']

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

.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'))

.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'))

.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就已被修饰,添加了验证功能

 

登录乐搏学院官网

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

 

本文出自 “” 博客,请务必保留此出处

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

你可能感兴趣的文章
BZOJ2064:分裂——题解
查看>>
poj 1797 Heavy Transportation(最短路径Dijkdtra)
查看>>
[转] 拉格朗日对偶
查看>>
WPF 在事件中绑定命令
查看>>
《工作DNA》读后感
查看>>
基于WinDbg的内存泄漏分析
查看>>
《小故事》
查看>>
气象预警采集及推送
查看>>
【SSH网上商城项目实战29】使用JsChart技术在后台显示商品销售报表
查看>>
python 基础复习 09 之基础函数
查看>>
Extjs 4
查看>>
教你使用Android SDK布局优化工具layoutopt
查看>>
Java内存模型(JMM)以及 垃圾回收机制 小结
查看>>
开源3D游戏引擎Irrlicht简介
查看>>
如何花更少的时间学习更多的知识
查看>>
学习鸟哥的Linux私房菜笔记(8)——文件查找与文件管理2
查看>>
day04 列表 增删改查 元组 range
查看>>
php 调用百度sms来发送短信的实现示例
查看>>
android 小结
查看>>
ThinkPHP5分页样式设置
查看>>