标签:boa oar world head 比较 rate name 实现 init
写个验证用户登录的装饰器:在调用函数前,先检查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 = ‘12345678‘
需将此装饰器加在每个需要验证登录的请求方法上即可
注意,必需加在route方法后
@app.route(‘/admin‘)
@login_required
def admin():
return ‘<h1>Admin Dashboard</h1>‘
可以直接添加路由。
def fun_view():
return ‘<h1>view
function test!</h1>‘
app.add_url_rule(‘/viewfun‘, view_func=fun_view)
验证一下效果:
可以查看app的路由参数:
Map([<Rule ‘/viewfun‘ (HEAD, GET, OPTIONS) -> fun_view>,
直接访问也可以
装饰器本质上是一个闭包函数,可以把它当函数使用:
app.add_url_rule(‘/foo‘, view_func=login_required(views.foo))
之前的视图都是函数,但它也可以通过类来实现:
view_func这个参数,要使用as_view这个方法来转换
如果指定了endpoint,那么在使用url_for反转的时候,就要使用endpoint指定的那个值,如果没有指定那个值,就使用as_view中指定的视图名字来作为反转。
类视图有以下的好处,可以将一些共性的东西抽取出来放到父视图中,子视图直接继承就可以了,但是也不是说所有的视图都要使用类视图,这个要根据实际情况来定。
class Plugview1(View):
def dispatch_request(self, **kw):
text = ‘这里是pluggable
test页面。‘
return render_template(‘plug_view.html‘, text1=text, name=kw[‘name‘])
from .views import Plugview1
view_t = Plugview1.as_view(‘plugview‘)
app.add_url_rule(‘/plugview/‘, view_func=view_t)
app.add_url_rule(‘/plugview/<name>‘, view_func=view_t)
我们创建了一个”flask.views.View”的子类,并覆盖了其”dispatch_request()”函数,渲染视图的主要代码必须写在这个函数里。然后我们通过”as_view()”方法把类转换为实际的视图函数,”as_view()”必须传入一个唯一的视图名。此后,这个视图就可以由”app.add_url_rule”方法绑定到路由上了。
效果展示:Map([<Rule ‘/plugview/‘ (HEAD, OPTIONS, GET) -> plugview>,
这个例子比较简单,只是为了介绍怎么用视图类,体现不出它的灵活性,我们再看个例子:指定模板
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请求。
上节介绍的HTT对于RESTFul类型的应用来说,有没有更简单的方法,比如省去那些if, else判断语句呢?Flask中的”flask.views.MethodView”可以。
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, pk=‘id‘, pk_type=‘int‘):
view_func = view.as_view(endpoint)
app.add_url_rule(url, defaults={pk: None},
view_func=view_func,
methods=[‘GET‘, ])
app.add_url_rule(url, view_func=view_func,
methods=[‘POST‘, ])
app.add_url_rule(‘%s<%s:%s>‘
% (url, pk_type, pk), view_func=view_func,
methods=[‘GET‘, ‘PUT‘, ‘DELETE‘])
from .views import UserAPI
register_api(UserAPI, ‘user_api‘, ‘/users/‘, pk=‘user_id‘)
现在,一个”register_api()”就可以绑定一个API了
<Rule ‘/users/‘ (OPTIONS, POST) -> user_api>,
<Rule ‘/users/<user_id>‘ (GET, PUT, DELETE, OPTIONS, HEAD) -> user_api>,
<Rule ‘/users/‘ (GET, OPTIONS, HEAD) -> user_api>])
标签:boa oar world head 比较 rate name 实现 init
原文地址:https://www.cnblogs.com/wodeboke-y/p/11093568.html