(django)11类视图
目录
使用函数方式定义的视图叫函数视图,虽然使用方便,便于理解,但是当一个s视图有多种请求方式的时候,变需要使用分支来编写不同请求方式对应的逻辑。
使用函数视图,代码看上去是这样子的
def my_view(request): if request.method == 'get': return httpresponse("get") if request.method == 'post': return httpresponse("post")
1. 使用类视图
基于类的视图的核心是允许你用不同的实例方法来响应不同的http请求方法,而不是在一个视图函数中使用条件分支代码来实现。
创建类视图
使用类视图,代码是这样子的
from django.views import view class classview(view): def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
类视图需要继承django提供的 view
类,使用 from django.views import view
导入
注册路由
配置类视图的时候,使用类视图的 as_view
方法注册路由
urlpatterns = [ url(r'^class_view', views.classview.as_view(), name="class_view") ]
as_view
会返回类中一个方法的引用,它会到 view
中,执行 dispatch
方法, dispatch
会方法会在类中查找类似get\post之类的类方法,然后和请求方式进行匹配,匹配上了,就返回该方法的引用。
如果向上边的类视图发送一个 get
请求,他会把 get
转换为小写形式并和类中的方法进行匹配,然后匹配到 get
方法,会把 get
方法的引用返回到 as_view
调用处。所以在 get
请求下最后 as_view
是 get
方法的引用。
类视图使用装饰器
可以使用装饰器为类视图增加功能,使用装饰器有三种方式。
- 在url配置中装饰
- 在类视图中装饰
- 使用mixin扩展类
为了便于理解,使用下边的案例做演示
def decorator(func): def wrapper(request, *args, **kwargs): print('装饰器被调用') return func(request, *args, **kwargs) return wrapper class classview(view): def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
在url中装饰
url(r'^class_view', views.decorator(views.classview.as_view()), name="class_view")
发送 get
或者 post
类型请求打印结果
装饰器被调用
在url中调用该函数,并把 as_view
方法传入即可,这种方式会把所有被请求的函数都进行装饰。
这种方法把装饰放到了url配置中,不利于代码的完整性和可读性,所以一般情况下不使用。
在类视图中装饰
在类视图中使用装饰器不能直接装饰,需要使用 method_decorator
把装饰器转换位适用于类的装饰器。
在我们写的装饰器中,内层函数接收的参数为 request
def decorator(func): def wrapper(request, *args, **kwargs): print('装饰器被调用') return func(request, *args, **kwargs) return wrapper
而在类视图的方法中,第一个参数是 self
,所以要使用 method_decorator
把装饰器的第一个参数补充为 self
以使用类视图中的方法。
也可以手动为装饰器添加参数 self
def decorator(func): def wrapper(self, request, *args, **kwargs): print('装饰器被调用') return func(self, request, *args, **kwargs) return wrapper
装饰所有方法
可以重写并装饰类的 dispatch
方法,代码如下
class classview(view): @method_decorator(decorator) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
使用 get
或者 post
方式请求,都会执行装饰器,打印结果
装饰器被调用
只装饰某一个方法
class classview(view): @method_decorator(decorator) def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
只有使用 get
方式请求,才会执行装饰器,打印结果
装饰器被调用
post
方式不会执行装饰器。
method_decorator 的 name 参数
装饰全部方法
@method_decorator(decorator, name="dispatch") class classview(view): def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
指定被装饰的方法
@method_decorator(decorator, name="get") class classview(view): def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
使用mixin扩展类
扩展类使用了 python 多继承的 mro
特性。
class mymixin(object): @classmethod def as_view(cls, *args, **kwargs): view = super().as_view(*args, **kwargs) view = decorator(view) return view class classview(mymixin, view): def get(self, request): return httpresponse("get") def post(self, request): return httpresponse("post")
这种方式会装饰所有方法,可以使用这种方式为方法添加多个装饰器。
上一篇: 数据分析——matplotlib