第5天:基于类的视图与中间件
- ?類視圖引入
- ?類視圖的定義與使用
- ?類視圖實現(xiàn)的原理
- ?在類視圖中使用裝飾器
- ?類視圖多繼承&Minx擴展類
- ?中間件
類視圖引入
以函數(shù)的方式定義的視圖成為函數(shù)視圖,函數(shù)視圖便于理解。但是遇到一個視圖對應的路徑提供了多種不同HTTP請求方式的支持時,就需要在一個函數(shù)中編寫不同的業(yè)務邏輯,代碼可讀性與復用性都不佳
def register(request):"""處理注冊"""#獲取請求方法,判斷是GET/POST請求if request.method == 'GET':#處理GET請求,返回注冊頁面return render(request, 'register.html')else:#處理POST請求,實現(xiàn)注冊邏輯return HttpResponse('這里實現(xiàn)注冊邏輯') 函數(shù)視圖示例在Django中也可以使用類來定義一個視圖,稱為類視圖
def register(View):"""類視圖 處理注冊"""def get(self, request):"處理GET請求, 返回注冊頁面"return render(request, 'register.html')def post(self, request):" 處理POST請求,實現(xiàn)注冊邏輯"return HttpResponse('這里實現(xiàn)注冊邏輯') 類視圖示例類視圖好處:
- 代碼可讀性好
- 類視圖相對于函數(shù)視圖通過繼承具有更高的可復用性
?
類視圖的定義與使用
我們要想使用類視圖必須繼承View
from django.views.generic import View
from django.views.generic import Viewclass DemoView(View):def get(self, request):return HttpResponse('get page')def post(self, request):return HttpResponse('post page') DemoView路由那里,我則需要使用該視圖的as_view方法轉(zhuǎn)換為函數(shù)
from .views import DemoViewurlpatterns = [url(r'^demo/$', DemoView.as_view(), name='demo') ] 路由配置?
類視圖實現(xiàn)的原理
?按住ctrl,點擊as_view
@classonlymethod def as_view(cls, **initkwargs):"""Main entry point for a request-response process."""...def view(request, *args, **kwargs):self = cls(**initkwargs) #cls就是DemoView類,生成對象if hasattr(self, 'get') and not hasattr(self, 'head'):self.head = self.getself.request = requestself.args = argsself.kwargs = kwargsreturn self.dispatch(request, *args, **kwargs)view.view_class = clsview.view_initkwargs = initkwargsupdate_wrapper(view, cls, updated=())update_wrapper(view, cls.dispatch, assigned=())return view #最終還是返回函數(shù)def dispatch(self, request, *args, **kwargs):..#根據(jù)請求方法判斷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_allowedreturn handler(request, *args, **kwargs) 相關(guān)源碼?
在類視圖中使用裝飾器
我們知道在函數(shù)視圖中,可以如下使用裝飾器?
def my_decorator(view_func):def wrapper(*args, **kwargs):print('裝飾器被調(diào)用')return view_func(*args, **kwargs)return wrapper@my_decorator def func_demo(request):return HttpResponse('func_demo') 函數(shù)視圖使用裝飾器在類視圖中使用為函數(shù)視圖準備的裝飾器時,不能直接添加裝飾器,需要使用method_decorator將其轉(zhuǎn)換為適用于類視圖方法的裝飾器。
?
?
類視圖多繼承& Minx擴展類
使用面向?qū)ο蠖嗬^承特性,可以通過定義父類(作為擴展類),在父類中定義想要想類視圖補充的方法,類視圖繼承這些擴展類,便可實現(xiàn)代碼服用。定義父類名稱通常以Mixin結(jié)尾
class ListModelMixin(object):"""list擴展類"""def list(self, request, *args, **kwargs):print('查詢多條數(shù)據(jù)')class CreateModelMixin(object):"""create擴展類"""def create(self, request, *args, **kwargs):print('新增一條數(shù)據(jù)')class DepartmentView(CreateModelMixin, ListModelMixin, View):"""同時繼承兩個擴展類,復用list和create方法"""def get(self, request):self.list(request)return HttpResponse('get page')def post(self, request):self.create(request)return HttpResponse('post page') 示例?
中間件
Django中的中間件是一個輕量級、底層的插件系統(tǒng),可以介入Django的請求和響應處理過程,修改Django的輸入或輸出。中間件的設(shè)計為開發(fā)者提供了一種無侵入式的開發(fā)方式,增強了Django框架的健壯性。我們可以可以使用中間件,在Django處理視圖的不同階段對輸入或輸出進行干預。
1、定義一個中間件,在項目中新建一個middlewares.py文件,然后在該文件中定義中間件類:
from django.utils.deprecation import MiddlewareMixin# 定義中間件類: 通過繼承Django的MiddlewareMixin擴展類實現(xiàn) class MyMiddleware(MiddlewareMixin):def __init__(self, get_response=None):# 服務器啟動,初始化中間件類時被調(diào)用,只執(zhí)行一次super().__init__(get_response)print('init')def process_request(self, request):print('before 視圖')# 注意:可以返回None或者response對象,如果返回response對象,則視圖函數(shù)就不會再執(zhí)行了def process_response(self, request, response):print('after 視圖')return response 自定義中間件2、在settings.py文件中添加中間件
?
3、定義一個視圖進行測試
def index(request):print('====index===')return HttpResponse('hello world')?
多個中間件的執(zhí)行順序
#1、再定義一個中間件類class MyMiddleware2(MiddlewareMixin):def __init__(self, get_response=None):super().__init__(get_response)print('init 2')def process_request(self, request):print('before 視圖 2')def process_response(self, request, response):print('after 視圖 2')return response#2、注冊MIDDLEWARE = ['django.middleware.security.SecurityMiddleware',...'middlewares.MyMiddleware', # 注冊中間件'middlewares.MyMiddleware2', ]#3、執(zhí)行結(jié)果 before 視圖before 視圖 2==index==after 視圖 2after 視圖#4、結(jié)論 對于視圖之前執(zhí)行的 process_request 方法,先 注冊的中間件先執(zhí)行 對于視圖之后執(zhí)行的 process_response 方法,后 注冊的中間件先執(zhí)行 示例說明轉(zhuǎn)載于:https://www.cnblogs.com/sellsa/p/10745562.html
總結(jié)
以上是生活随笔為你收集整理的第5天:基于类的视图与中间件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: JavaScript 学习中的帮助记忆(
- 下一篇: [HNOI2007]分裂游戏
