Django类视图的引入以及类视图加装饰器

mac2026-04-23  12

Django的代码逻辑可以使用函数视图, 并且函数视图更加直观, 更加方便理解, 为什么要引入类视图呢?
如果遇到一个视图的路径对应多种http请求方式怎么办? # 伪代码 if request.method == 'GET': pass elif request.method == 'POST': pass ...... 是不是逻辑代码会加入大量的判断, 代码会出现大量的冗余, 可读性, 和复用性都不佳
类视图的引入
定义类视图要继承于父类View, View里面做了什么? @classonlymethod def as_view(cls, **initkwargs): """ Main entry point for a request-response process. """ ...省略代码... def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 调用dispatch方法,按照不同请求方式调用不同请求方法 return self.dispatch(request, *args, **kwargs) ...省略代码... # 返回真正的函数视图 return view def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) 由上面的部分源码可见, View内部做了 as_view()是一个类方法, 只有类对象才能调用, 它是一个闭包函数, 返回了view()函数view()函数内部又调用了dispatch()函数, 这是一个调度函数dispatch()函数, 它判断发起的是什么请求, 然后调用对应的函数 再贴上一段代码(l类视图和它对应的路由, 帮助理解上面的内容) class IndexView(View): def get(self, request): return HttpResponse('hello world!') url(r'^index/$', views.IndexView.as_view()),
类视图的引入带来了什么问题? 怎么样解决?
Django自带的装饰器, 装饰器一般情况下, 只能装饰函数视图, 那么怎么装饰类视图呢?第一时间会想到, 类视图里面都是函数, 我把装饰器加在里面的函数上面, 问题不就解决了吗?那么如果我类视图里面的函数全部都要加上装饰器, 这样做是不是麻烦呢?

解决方法一:

# 给路由加装饰器 url(r'^index/$', 装饰器(views.IndexView.as_view())), # 缺点: 不利于代码的维护

解决方法二:

# 首先得理解, 要让每个函数都加上装饰器, 这里的每个函数都会走哪个函数? # 都会走上面的调度函数dispatch()函数, 所以给dispatch()加上装饰器, 就可以解决了 # 可以重写上面的dispatch()函数, 这里就不说那种不优雅的方法了 # django提供了更加优雅的方法, "@method_decorator(装饰器名, name='想装饰的函数')", 这个装饰器可以把装饰器装换为适合类视图使用的装饰器, 这个装饰器也可以为某个特定的方法加装饰器 # 为全部请求方法添加装饰器 @method_decorator(my_decorator, name='dispatch') class DemoView(View): def get(self, request): print('get方法') return HttpResponse('ok') def post(self, request): print('post方法') return HttpResponse('ok') # 为特定请求方法添加装饰器 @method_decorator(my_decorator, name='get') class DemoView(View): def get(self, request): print('get方法') return HttpResponse('ok') def post(self, request): print('post方法') return HttpResponse('ok')
最新回复(0)