类视图
- 以函数的方式定义的视图称为函数视图,函数视图便于理解。但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳。
- 在Django中也可以使用类来定义一个视图,称为类视图。使用类视图可以将视图对应的不同请求方式以类中的不同方法来区别定义。
方式一
def my_decorator(func):
"""自定义的装饰器"""
def wrapper(request,*args,**kwargs):
print("自动以装饰器被调用了")
print("请求路径为: %s" % request.path)
return func(request, *args, **kwargs)
return wrapper
class DemoView(View):
"""第一种方法"""
# 装饰了dsipasth方法就可以实现两个函数的装饰,dsipasth是as_view函数的一个内部函数
@method_decorator(my_decorator)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
def get(self,request):
print("get 方法")
return HttpResponse("get page")
def post(self,request):
print("post 方法")
return HttpResponse("post page")
在urls
文件中要使用as_view()
将类转化成视图
url("demo1",DemoView.as_view()),
方式二
def my_decorator(func):
"""自定义的装饰器"""
def wrapper(request,*args,**kwargs):
print("自动以装饰器被调用了")
print("请求路径为: %s" % request.path)
return func(request, *args, **kwargs)
return wrapper
"""
method_decorator装饰器还支持使用name参数指明被装饰的方法
method_decorator有两个参数,一个是装饰器的名字第二用name指定被装饰的函数
"""
# @method_decorator(my_decorator, name='get') # 为特定请求方法添加装饰器
@method_decorator(my_decorator,name="dispatch") # 为全部请求方法添加装饰器
class DemoVeiw2(View):
"""第二种方法"""
def get(self,request):
print("get 方法")
return HttpResponse("get page")
def post(self,request):
print("post 方法")
return HttpResponse("post page")
在urls
文件中要使用as_view()
将类转化成视图
url("demo2",DemoVeiw2.as_view()),
方式三
def my_decorator(func):
"""自定义的装饰器"""
def wrapper(request,*args,**kwargs):
print("自动以装饰器被调用了")
print("请求路径为: %s" % request.path)
return func(request, *args, **kwargs)
return wrapper
def my_decorator3(func):
def wrapper(self, request, *args, **kwargs): # 此处增加了self
print('自定义装饰器被调用了')
print('请求路径%s' % request.path)
return func(self, request, *args, **kwargs) # 此处增加了self
return wrapper
"""
函数视图准备的装饰器,其被调用时,第一个参数用于接收request对象
而类视图中请求方法被调用时,传入的第一个参数不是request对象,而是self 视图对象本身,第二个位置参数才是request对象
method_decorator的作用是为函数视图装饰器补充第一个self参数,以适配类视图方法。
如果将装饰器本身改为可以适配类视图方法的,类似如下,则无需再使用method_decorator。
"""
class DemoVeiw3(View):
"""第三种方法"""
@my_decorator3 # 装饰dispatch就可以全部装饰
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
def get(self,request):
print("get 方法")
return HttpResponse("get page")
def post(self,request):
print("post 方法")
return HttpResponse("post page")
在urls
文件中要使用as_view()
将类转化成视图
url("demo3",DemoView.as_view()),
方式四(Minxin扩展类)
"""
Minxin扩展类
"""
def my_decorator4(func):
"""自定义装饰器"""
def wrapper(request, *args, **kwargs): # 此处增加了self
print('自定义装饰器被调用了')
print('请求路径%s' % request.path)
return func(request, *args, **kwargs) # 此处增加了self
return wrapper
# 程序员中不成文规定,扩展类类名使用Minxin结尾
class MyDecoratorMinxin(object):
"""构造Minxin扩展类"""
@classmethod
def as_view(cls, *args, **kwargs):
view = super().as_view(*args, **kwargs)
view = my_decorator4(view)
return view
"""
实际工作中会有不止一个的扩展类,所以使用多继承的必然的,
这些扩展类都集成自object,但是object中并没有as_view方法,
所以在一个类要集成扩展类达到装饰目的时一定要在最后继承View类进行兜底
"""
class DemoVeiw4(MyDecoratorMinxin,View): # 多继承,最后继承View类进行兜底
"""第四种方法"""
def get(self,request):
print("get 方法")
return HttpResponse("get page")
def post(self,request):
print("post 方法")
return HttpResponse("post page")
在urls
文件中要使用as_view()
将类转化成视图
url("demo4",DemoView.as_view()),