flask中的可拨插视图主要是为了代码的复用。
可拨插视图其实是一个类,需要继承flask.views.View类,必须实现dispath_request()方法。dispath_request()方法中的代码就相当于普通视图函数中的代码。并且,需要采用add_url_rule()函数生成路由规则。在add_url_rule()函数中需要通过as_view()函数将flask.view.View子类转化为视图函数。
as_view()函数原型为 as_view(name,*class_args,**class_kwargs)
其中name为flask.view.View子类的名称(小写。试了一下,似乎只要是一个字符串就可以,仅仅是一个名字),clas_args和class_kwargs将传给类的构造器。
decorators=[]:装饰器,当类转化为视图函数时装饰该视图函数。当decorators有多个装饰器时,将依次执行。因此,可以自己写装饰器。
methods=None:与route()中的methods一样,有GET、POST等。
如:
from flask.views import View class ShowUsers(View): methods=['GET','POST'] def dispatch_request(self): if request.method=='GET': users=User.query.all() return render_template("user.html",objects=users) if request.method=='POST': ....... app.add_url_rule('/users/',view_func=ShowUsers.as_view('show_users'))
基于方法调度:
flask.views.MethodView类可以轻易为每个HTTP方法提供相对应的不同函数。在这个类中,每个HTTP方法都映射到一个同名函数(函数名称为小写字母)
from flask.views import MethodView
class UserAPI(MethodView):
def get(self):
users=User.query.all()
def post(self):
user=User.from_form_data(request.form)
app.add_url_rule('/users/',view_func=UserAPI.as_view('userapi'))
使用这种方式,不必提供methods属性,它会自动使用相应的类方法。
网络 API 经常直接对应 HTTP 变量,因此很有必要实现基于 MethodView 的 API 。即多数时候, API 需要把不同的 URL 规则应用到同一个方法视图。例如,假设你需要这样使用一个 user 对象:
URL 方法 说明
/users/ GET 给出一个包含所有用户的列表
/users/ POST 创建一个新用户
/users/<id> GET 显示一个用户
/users/<id> PUT 更新一个用户
/users/<id> DELETE 删除一个用户
那么如何使用 MethodView 来实现呢?方法是使用多个规则对应 到同一个视图。
假设视图是这样的:
class UserAPI(MethodView): def get(self, user_id): if user_id is None: # 返回一个包含所有用户的列表 pass else: # 显示一个用户 pass def post(self): # 创建一个新用户 pass def delete(self, user_id): # 删除一个用户 pass def put(self, user_id): # update a single user pass
那么如何把这个视图挂接到路由系统呢?方法是增加两个规则并为每个规则显式声明 方法:
user_view = UserAPI.as_view('user_api') app.add_url_rule('/users/', defaults={'user_id': None}, view_func=user_view, methods=['GET',]) app.add_url_rule('/users/', view_func=user_view, methods=['POST',]) app.add_url_rule('/users/<int:user_id>', view_func=user_view, methods=['GET', 'PUT', 'DELETE'])
如果你有许多类似的 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'])
register_api(UserAPI, 'user_api', '/users/', pk='user_id')