写个验证用户登录的装饰器:在调用函数前,先检查session里有没有用户

from functools import wraps
from flask import session, abort def login_required(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if not 'user' in session:
abort(401)
return func(*args, **kwargs)
return decorated_function app.secret_key = ''

需将此装饰器加在每个需要验证登录的请求方法上即可

@app.route('/admin')
@login_required
def admin():
return '<h1>Admin Dashboard</h1>'

URL集中映射

Flask也支持像Django一样,把URL路由规则统一管理,而不是写在视图函数上

我们先来写个视图函数,将它放在一个”views.py”文件中:

def foo():
return '<h1>Hello Foo!</h1>'

然后在Flask主程序上调用”app.add_url_rule”方法:

app.add_url_rule('/foo', view_func=views.foo)

这样,路由”/foo”就绑定在”views.foo()”函数上了,效果等同于在”views.foo()”函数上加上”@app.route(‘/foo’)”装饰器。通过”app.add_url_rule”方法,我们就可以将路由同视图分开,将路由统一管理,实现完全的MVC。

装饰器本质上是一个闭包函数,所以我们当然可以把它当函数使用:

app.add_url_rule('/foo', view_func=login_required(views.foo))

可插拔视图Pluggable View

from flask.views import View

class HelloView(View):
def dispatch_request(self, name=None):
return render_template('hello-view.html', name=name) view = HelloView.as_view('helloview')
app.add_url_rule('/helloview', view_func=view)
app.add_url_rule('/helloview/<name>', view_func=view)

我们创建了一个”flask.views.View”的子类,并覆盖了其”dispatch_request()”函数,渲染视图的主要代码必须写在这个函数里。然后我们通过”as_view()”方法把类转换为实际的视图函数,”as_view()”必须传入一个唯一的视图名。此后,这个视图就可以由”app.add_url_rule”方法绑定到路由上了。上例的效果,同本篇第一节中”/hello”路径的效果,完全一样。

这个例子比较简单,只是为了介绍怎么用视图类,体现不出它的灵活性,我们再看个例子:

class RenderTemplateView(View):
def __init__(self, template):
self.template = template def dispatch_request(self):
return render_template(self.template) app.add_url_rule('/hello', view_func=RenderTemplateView.as_view('hello', template='hello-view.html'))
app.add_url_rule('/login', view_func=RenderTemplateView.as_view('login', template='login-view.html'))

视图装饰器支持

class HelloView(View):
decorators = [login_required] def dispatch_request(self, name=None):
return render_template('hello-view.html', name=name)

我们只需将装饰器函数加入到视图类变量”decorators”中即可。它是一个列表,所以能够支持多个装饰器,并按列表中的顺序执行。

请求方法的支持

当我们的视图要同时支持GET和POST请求时,视图类可以这么定义:

class MyMethodView(View):
methods = ['GET', 'POST'] def dispatch_request(self):
if request.method == 'GET':
return '<h1>Hello World!</h1>This is GET method.'
elif request.method == 'POST':
return '<h1>Hello World!</h1>This is POST method.' app.add_url_rule('/mmview', view_func=MyMethodView.as_view('mmview'))

我们只需将需要支持的HTTP请求方法加入到视图类变量”methods”中即可。没加的话,默认只支持GET请求。

基于方法的视图

上节介绍的HTTP请求方法的支持,的确比较方便,但是对于RESTFul类型的应用来说,有没有更简单的方法,比如省去那些if, else判断语句呢?Flask中的”flask.views.MethodView”就可以做到这点,它是”flask.views.View”的子类。我们写个user API的视图吧:

from flask.views import MethodView

class UserAPI(MethodView):
def get(self, user_id):
if user_id is None:
return 'Get User called, return all users'
else:
return 'Get User called with id %s' % user_id def post(self):
return 'Post User called' def put(self, user_id):
return 'Put User called with id %s' % user_id def delete(self, user_id):
return 'Delete User called with id %s' % user_id

现在我们分别定义了get, post, put, delete方法来对应四种类型的HTTP请求,注意函数名必须这么写。怎么将它绑定到路由上呢?

user_view = UserAPI.as_view('users')
# 将GET /users/请求绑定到UserAPI.get()方法上,并将get()方法参数user_id默认为None
app.add_url_rule('/users/', view_func=user_view,
defaults={'user_id': None},
methods=['GET',])
# 将POST /users/请求绑定到UserAPI.post()方法上
app.add_url_rule('/users/', view_func=user_view,
methods=['POST',])
# 将/users/<user_id>URL路径的GET,PUT,DELETE请求,
# 绑定到UserAPI的get(), put(), delete()方法上,并将参数user_id传入。
app.add_url_rule('/users/<user_id>', view_func=user_view,
methods=['GET', 'PUT', 'DELETE'])

上例中”app.add_url_rule()”可以传入参数default,来设置默认值;参数methods,来指定支持的请求方法。

如果API多,有人觉得每次都要加这么三个路由规则太麻烦,可以将其封装个函数:

def register_api(view, endpoint, url, primary_id='id', id_type='int'):
view_func = view.as_view(endpoint)
app.add_url_rule(url, view_func=view_func,
defaults={primary_id: None},
methods=['GET',])
app.add_url_rule(url, view_func=view_func,
methods=['POST',])
app.add_url_rule('%s<%s:%s>' % (url, id_type, primary_id),
view_func=view_func,
methods=['GET', 'PUT', 'DELETE']) register_api(UserAPI, 'users', '/users/', primary_id='user_id')

现在,一个”register_api()”就可以绑定一个API了

延迟加载视图

当某一视图很占内存,而且很少会被使用,我们会希望它在应用启动时不要被加载,只有当它被使用时才会被加载。也就是接下来要介绍的延迟加载。Flask原生并不支持视图延迟加载功能,但我们可以通过代码实现。这里,我引用了官方文档上的一个实现。

from werkzeug import import_string, cached_property

class LazyView(object):
def __init__(self, import_name):
self.__module__, self.__name__ = import_name.rsplit('.', 1)
self.import_name = import_name @cached_property
def view(self):
return import_string(self.import_name) def __call__(self, *args, **kwargs):
return self.view(*args, **kwargs)
def bar():
return '<h1>Hello Bar!</h1>'

我们先写了一个LazyView,然后在views.py中定义一个名为bar的视图函数:

现在让我们来绑定路由:

app.add_url_rule('/lazy/bar', view_func=LazyView('views.bar'))

路由绑定在LazyView的对象上,因为实现了__call__方法,所以这个对象可被调用,不过只有当’/lazy/bar’地址被请求时才会被调用。此时”werkzeug.import_string”方法会被调用,看了下Werkzeug的源码,它的本质就是调用”__import__”来动态地导入Python的模块和函数。所以,这个”view.bar”函数只会在’/lazy/bar’请求发生时才被导入到主程序中。不过要是每次请求发生都被导入一次的话,开销也很大,所以,代码使用了”werkzeug.cached_property”装饰器把导入后的函数缓存起来

同上一节的”register_api()”函数一样,你也可以把绑定延迟加载视图的代码封装在一个函数里。

def add_url_for_lazy(url_rule, import_name, **options):
view = LazyView(import_name)
app.add_url_rule(url_rule, view_func=view, **options) add_url_for_lazy('/lazy/bar', 'views.bar')

Flask 视图的更多相关文章

  1. Flask视图函数报fmalformed url rule错误的原因

    Flask视图函数报fmalformed url rule错误,原因可能是包含中文字符了 把标点符号都重新写一遍英文格式的,可能就不会报这个了

  2. flask 视图函数的使用

    flask框架 视图函数当中 各种实用情况简单配置 1 建立连接 2 路由参数 3 返回网络状态码 4 自定义错误页面 5 重定向 6 正则url限制 和 url 优化 7 设置和获取cookie # ...

  3. Flask 视图,中间件

    视图 FBV def index(nid): """ 请求相关信息 request.method # 请求方式 request.args # get 方式的参数获取 re ...

  4. Flask视图函数与普通函数的区别,响应对象Response

    视图函数与普通函数看似没什么区别,其实他们的返回值上有着很大的区别. from flask import Flask app = Flask(__name__) @app.route('/hello' ...

  5. Flask 视图,模板,蓝图.

    https://www.cnblogs.com/wupeiqi/articles/7552008.html 1. 配置文件 from flask import Flask app =Flask(__n ...

  6. Flask视图函数与模板语法

    1.Django中的CBV模式 ​ 2.Flask中的CBV和FBV def auth(func):     def inner(*args, **kwargs):         result =  ...

  7. 3.flask视图进阶

    1.add_url_rule和app.route原理剖析 from flask import Flask app = Flask(__name__) # 下面是我们定义一个路由和对应视图的常用方法 ' ...

  8. 1.flask视图和URL

    1.第一个flask程序 from flask import Flask ''' Flask这个类是项目的核心,以后很多操作都是基于这个类的对象 注册URL等等,都是基于这个类 ''' app = F ...

  9. 第五章 Flask视图高级

    add_url_rule和app.route原理剖析 add_url_rule add_url_rule(rule,endpoint=None,view_func=None) 这个方法用来添加url与 ...

随机推荐

  1. 【BZOJ2134】单位错选(数学期望,动态规划)

    [BZOJ2134]单位错选(数学期望,动态规划) 题面 BZOJ 题解 单独考虑相邻的两道题目的概率就好了 没了呀.. #include<iostream> #include<cs ...

  2. 【BZOJ4237】稻草人(CDQ分治,单调栈)

    [BZOJ4237]稻草人(CDQ分治,单调栈) 题面 BZOJ 题解 \(CDQ\)分治好题呀 假设固定一个左下角的点 那么,我们可以找到的右下角长什么样子??? 发现什么? 在右侧是一个单调递减的 ...

  3. Luogu 睡觉困难综合征 ([NOI2014]起床困难综合症)

    一.[NOI2014]起床困难综合症 题目描述 网址:https://daniu.luogu.org/problemnew/show/2114 大意: 有一条链,链上每一个节点包含一个位运算f 与 一 ...

  4. telnet命令使用详解

    telnet命令用于登录远程主机,对远程主机进行管理.telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh方式了.但仍然有很多别的系统可能采 ...

  5. Redis之Set

    一.Redis之Set简介 1. Set是String类型的无序集合(元素成员唯一). 2. Set是通过hash表实现的,添加.删除.查找的复杂度都是O(1). 3. 每个集合最大成员数为232-1 ...

  6. NancyFX 第三章 Web框架

    如果使用Nancy作为一个WEB框架而言,会有什么不同?实际上很多. 在使用Nancy框架为网页添加Rest节点和路由和之前的Rest框架中是相同的,这方面没有什么需要学习的了.Nancy采用一贯的处 ...

  7. 属性动画 ValueAnimator 运行原理全解析

    最近下班时间都用来健身还有看书了,博客被晾了一段时间了,原谅我~~~~ 提问环节 好,废话不多说,之前我们已经分析过 View 动画 Animation 运行原理解析,那么这次就来学习下属性动画的运行 ...

  8. select子句和三种子查询

    一.select子句 五种子句 Where.group by.having.order by.limit Where.group by.having.order by.limit运用的这个顺序不能变 ...

  9. 格式化JSON数据

    function formatJson(json, options) { var reg = null, formatted = '', pad = 0, PADDING = ' '; options ...

  10. 前端的UI设计与交互之文案篇

    在界面中,我们需要通过对话的方式与用户产生共鸣.精准.清晰的语言会更容易让用户理解,合适的语气更容易让用户建立信任感.因此在界面设计时,文案也应当被重视. 在使用和书写文案时有以下几点需要注意:从用户 ...