django處理一個Request的過程是首先通過django 中間件,然后再通過默認的URL方式進行的。所以說我們要做的就是在django 中間件這個地方把所有Request攔截住,用我們自己的方式完成處理以后直接返回Response,那么我們可以簡化原來的設計思路,把中間件不能處理的 Request統統不管,丟給Django去處理。
如果你要在用戶登錄或者其它的處理過程中完成自己的一些處理,比如進行權限控制,對返回結果作一些處理,可以使用python的修飾器,但有個缺點就是要在每個視圖前面都添加修飾器,當初我就是這么做的,太累了。后來發現 django 中間件非常棒,可以進行全局控制,而且可以提高性能。提倡這種dry的哲學風格設計非常的有意思,
先說下django 中間件的安裝方法:
為了激活中間件組件,把它添加到你的settings模塊的MIDDLEWARE_CLASSES列表中,在MIDDLEWARE_CLASSES里,每個中間件組件通過一個字符串來表示:完整的到中間件的類名的Python路徑,例如,這里是通過django-admin.py startPRoject創建的
默認的MIDDLEWARE_CLASSES:
MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', #'decorators.middleware.DecoratorsMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware',)
Django安裝部需要任何中間件--例如MIDDLEWARE_CLASSES可以為空,如果你想這樣的話--但是強烈建議你使用CommonMiddleware 順序是有意義的,在請求和視圖階段,Django使用MIDDLEWARE_CLASSES給定的順序申請中間件,而在應答和異常階段,Django使用相反的順序申請中間件,即DjangoMIDDLEWARE_CLASSES當作一種視圖方法的"包裝器",在請求時,它自頂向下申請這個列表的中間件到視圖,而在應答時它反序進行.
再說下django 中間件的定義方法:
* 請求預處理:process_request(self, request) :
該方法在請求被接收和URL被解析來決定運行哪個視圖之前立即調用,它傳遞你可能想修改的HttpRequest對象 process_request()應該返回None或者HttpResponse對象,如果它返回None,Django將繼續處理該請求,執行任何其它的中間件然后是合適的視圖。如果請求中間件返回HttpResponse對象,Django將不會再調用其它任何中間件(任何類型)或者合適的視圖,它將返回該應答。
* 視圖預處理:process_view(self, request, view, args, kwargs) :
該方法在請求中間件運行后和URL被解析到一個視圖后和視圖實際上被調用之前被調用,
參數說明:
* request HttpRequest對象
* view, Django將調用來執行該請求的視圖函數,它是實際上的方法對象本身,而不是方法名字符串
* args 將被傳遞給視圖的位置參數列表,不包括request參數(它一直是視圖的第一個參數)
* kwargs 將被傳遞給視圖的關鍵字參數字典
像process_request()一樣,process_view()應該返回None或者HttpResponse對象,如果它返回None,Django將繼續處理請求執行任何其它的視圖中間件然后是合適的視圖,如果視圖中間件返回HttpResponse對象,Django將不會再調用其它任何中間件或者合適的視圖,它將返回該應答
* 應答后處理:process_response(self, request, response)
該方法在視圖方法已經調用和應答生成后調用,這是中間件修改應答輸出的地方,輸出壓縮(見下)是應答中間件的一個顯然的應用參數應該非常自明了--request是請求對象,response是從視圖返回的應答對象不像請求和視圖中間件,它們可以返回None,process_response()必須返回一個HttpResponse對象,該應答可以是傳遞給該
方法的原始應答(可能被修改了)或者新的應答
* 異常后處理:process_exception(self, request, exception)
該方法只在出錯并且視圖觸發不可捕獲的異常時調用,不包括Http404異常,你可以使用這個鉤子來發送錯誤通知,在一個日志文件記錄信息,或者甚至嘗試自動恢復該錯誤。該方法的參數是我們一直處理的同樣的request對象和視圖方法觸發的真正的Exception對象exception。process_exception()可能返回一個作為應答顯示給瀏覽器的HttpResponse或者返回None來繼續Django內建的異常處理。
比如我們寫了個例子
MIDDLEWARE_CLASSES = (
'apps.auth.middleware.DecoratorsMiddleware',
)
然后DecoratorsMiddleware定義的方法是:
#coding=utf-8import urllibfrom django.template import RequestContextfrom django.shortcuts import render_to_responseclass DecoratorsMiddleware(object): """ 如果返回的對象是字典,就對它進行處理 """ def process_response(self, request, response): if type(response) == dict: param_dict = {} for k,v in request.GET.items(): if k == 'last_id': param_dict['last_id'] = response['ret'].get('last_id','') else: param_dict[k] = v.encode('utf-8') if not param_dict.get('last_id'): param_dict['last_id'] = response['ret'].get('last_id','') response['ret']['params'] = urllib.urlencode(param_dict) response['ret'] = dict(response['ret'], **param_dict) return render_to_response( response['template'], response['ret'], RequestContext(request, {}), ) return response
最后總結一下django 中間件不是很難,用一下就應該比較清楚了。
新聞熱點
疑難解答