类视图

之前我们接触的视图都是函数,所以一般简称视图函数。其实视图也可以基于类来实现,类视图的好处是支持继承,但是类视图不能跟函数视图一样,写完类视图还需要通过app.add_url_rule(url_rule,view_func)来进行注册。以下将对两种类视图进行讲解:

标准视图:

标准视图继承自flask.views.View,并且在子类中必须实现dispatch_request方法,这个方法类似于视图函数,也要返回一个基于Response或者其子类的对象。以下将用一个例子进行讲解:

  1. class BaseView(views.View):
  2. # 自定义方法,用来获取模板路径
  3. def get_template_name(self):
  4. raise NotImplementedError()
  5. # 必须实现的方法,用来处理请求的
  6. def dispatch_request(self):
  7. if request.method != 'GET':
  8. return 'method error'
  9. #这里从self.get_data()中获取数据,子类应该实现这个方法
  10. context = {'data':self.get_data()}
  11. return render_template(self.get_template_name(),**context)
  12. class UserView(BaseView):
  13. # 实现从父类继承的获取模板路径的方法
  14. def get_template_name(self):
  15. return 'user.html'
  16. # 重写获取数据的方法
  17. def get_data(self):
  18. return [{
  19. 'username': 'fake',
  20. 'avatar': 'http://www.baidu.com/'
  21. }]
  22. # 类视图通过add_url_rule方法和url做映射
  23. app.add_url_rule('/users/',view_func=UserView.as_view('userview'))

基于调度方法的视图:

Flask还为我们提供了另外一种类视图flask.views.MethodView,对每个HTTP方法执行不同的函数(映射到对应方法的小写的同名方法上),这对RESTful API尤其有用,以下将用一个例子来进行讲解:

  1. class UserAPI(views.MethodView):
  2. # 当客户端通过get方法进行访问的时候执行的函数
  3. def get(self):
  4. return jsonify({
  5. 'username':'xiaotuo',
  6. 'avatar':'http://www.baidu.com/'
  7. })
  8. # 当客户端通过post方法进行访问的时候执行的函数
  9. def post(self):
  10. return 'UNSUPPORTED!'
  11. # 通过add_url_rule添加类视图和url的映射,并且在as_view方法中指定该url的名称,方便url_for函数调用
  12. app.add_url_rule('/myuser/',view_func=UserAPI.as_view('userapiview'))

用类视图的一个缺陷就是比较难用装饰器来装饰,比如有时候需要做权限验证的时候,比如看以下例子:

  1. def user_required(f):
  2. def decorator(*args,**kwargs):
  3. if not g.user:
  4. return 'auth failure'
  5. return f(*args,**kwargs)
  6. return decorator

如果要在类视图上进行装饰,只能在as_view函数上进行装饰了,使用方式如下:

  1. view = user_required(UserAPI.as_view('users'))
  2. app.add_url_rule('/users/',view_func=view)

但是一个好消息是,从Flask 0.8开始,还可以通过在类中添加decorators属性来实现对视图的装饰:

  1. class UserAPI(views.MethodView):
  2. decorators = [user_required]
  3. ...