類視圖
- 以函數的方式定義的視圖稱爲函數視圖,函數視圖便於理解。但是遇到一個視圖對應的路徑提供了多種不同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()),