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
return self
.dispatch
(request
, *args
, **kwargs
)
...省略代码
...
return view
def dispatch(self
, request
, *args
, **kwargs
):
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
())),
解决方法二:
@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')