安徽新华电脑专修学院_安徽电脑培训_安徽电脑培训学校_合肥电脑培训

當前位置:首頁 > 網站舊欄目 > 學習園地 > 設計軟件教程 > 翻譯www.djangobook.com之第十六章:中間件

翻譯www.djangobook.com之第十六章:中間件
2010-01-13 23:43:58  作者:  來源:
有時你需要對每個Django處理的請求運行一段代碼,該代碼可能需要在視圖處理它之前修改請求,或者可能日志為了調試而
記錄關于請求的信息等等
Django的中間件框架本質上是進入Django的請求/應答處理的鉤子,它是全局改變Django的輸入和輸出的輕量的,低級的"插
件"系統
每個中間件組件負責一些專有的功能,如果你線性的閱讀本書,則你已經看到中間件好幾次了:
1,我們在第12章看到的所有俏皮的會話和用戶工具可能由一些小塊的中間件構成(更明確的,中間件使得你在視圖中可以得
到request.session和request.user)
2,第12章討論的站點寬度的緩存事實上只是一些中間件,如果視圖的應答已經被緩存則它們是調用你的視圖方法的捷徑
3,第15章的flatpages,redirects和csrf這些貢獻的apps都是通過使用中間件組件來施展它們的魔力
本章深入了解什么是中間件以及它怎樣工作,并解釋了你怎樣寫你自己的中間件

什么是中間件?
中間件事實上難以置信的簡單,一個中間件組件是簡單的遵守某一API的Python類--又是鴨子類型!在深入正式的API之前,讓
我們先來看看簡單的例子
高流量的站點通常需要在一個負載均衡代理后面部署Django(參考第12章),這會導致一些小的復雜性,其中一個是每個請求
的遠程IP(request.META["REMOTE_IP"])將為負載均衡者的IP,而不是真實的IP生成的請求,負載均衡通過設置特殊的頭部
X-Forwared-For到真實的請求IP地址來處理這些
所以這里是一些中間件讓代理后面運行的站點仍然可以在request.META["REMOTE_IP"]看到正確的IP地址:
Java代碼 復制代碼
  1. class SetRemoteAddrFromForwardedFor(object):   
  2.   
  3.     def process_request(self, request):   
  4.         try:   
  5.             real_ip = request.META['HTTP_X_FORWARDED_FOR']   
  6.         except KeyError:   
  7.             pass   
  8.         else:   
  9.             # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.   
  10.             # Take just the first one.   
  11.             real_ip = real_ip.split(",")[0]   
  12.             request.META['REMOTE_ADDR'] = real_ip  

如果它被安裝了(參考下面的),每個請求的X-Forwarded-For值將被自動插入到request.META['REMOTE_ADDR'],很簡單吧?
事實上,這個中間件作為Django的內建部分是一個足夠常見的需要,它位于django.middleware.http,你在下面可以看到一
些更多關于它的內容

安裝中間件
線性閱讀的讀者可能已經對此是老手了,如果你已經指定怎樣激活中間件則前面的一些章節中的許多例子將很好的工作
盡管如此,為了完整性考慮--以及為了考慮那些已經把本書的頁面撕破并攪亂它們并隨機閱讀它們的Julio Cortázar 迷們
讓我們來看看它
為了激活中間件組件,把它添加到你的settings模塊的MIDDLEWARE_CLASSES列表中,在MIDDLEWARE_CLASSES里,每個中間件
組件通過一個字符串來表示:完整的到中間件的類名的Python路徑,例如,這里是通過django-admin.py startproject創建的
默認的MIDDLEWARE_CLASSES:
Java代碼 復制代碼
  1. MIDDLEWARE_CLASSES = (   
  2.     'django.middleware.common.CommonMiddleware',   
  3.     'django.contrib.sessions.middleware.SessionMiddleware',   
  4.     'django.contrib.auth.middleware.AuthenticationMiddleware',   
  5.     'django.middleware.doc.XViewMiddleware',   
  6. )  

Django安裝部需要任何中間件--例如MIDDLEWARE_CLASSES可以為空,如果你想這樣的話--但是強烈建議你使用CommonMiddle
ware
順序是有意義的,在請求和視圖階段,Django使用MIDDLEWARE_CLASSES給定的順序申請中間件,而在應答和異常階段,Djang
o使用相反的順序申請中間件,即Django把MIDDLEWARE_CLASSES當作一種視圖方法的"包裝器":在請求時,它自頂向下申請這
個列表的中間件到視圖,而在應答時它反序進行

中間件方法
既然我們知道了什么是中間件和怎樣安裝它,讓我們來看看中間件類可能定義的所有可得到的方法

初始化:__init__(self)
如果中間件類定義了一個構造方法(即一個__init__方法),它應該不使用參數(除了標準的slef)
出于性能考慮,中間件類在長時間運行的服務器過程中只初始化一次,這意味著你不能指望每次請求運行時調用__init__,
只有在服務器啟動時調用一次
中間件類可能也使用初始化時間來刪除它們本身而不是被安裝,如果初始化時觸發django.exceptions.MiddlewareNotUsed異
常,則Django將從中間件堆棧刪除該中間件,你可能使用這點來檢查中間件類依賴的一些軟件,或者服務器是否運行在調試
模式下,或者任何其它可能讓你想禁止中間件的類型的環境

請求預處理:process_request(self, request)
該方法在請求被接收和URL被解析來決定運行哪個視圖之前立即調用,它傳遞你可能想修改的HttpRequest對象
process_request()應該返回None或者HttpResponse對象,如果它返回None,Django將繼續處理該請求,執行任何其它的中間
件然后是合適的視圖
如果請求中間件返回HttpResponse對象,Django將不會再調用其它任何中間件(任何類型)或者合適的視圖,它將返回該應答

視圖預處理:process_view(self, request, view, args, kwargs)
該方法在請求中間件運行后和URL被解析到一個視圖后和視圖實際上被調用之前被調用
傳遞給該視圖的參數為:
Argument           Explanation
request            HttpRequest對象
view               Django將會調用來樹立該請求的Python方法,它是實際上的方法對象本身,而不是方法名字符串
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內建的異常處理

例子
Django自帶一些中間件類--上面討論了--它們是很好的例子,閱讀它們的代碼應該給你中間件的力量的好的感覺
你也可以在Django的wiki上找到一些社區貢獻的例子:
http://code.djangoproject.com/wiki/ContributedMiddleware

內建的中間件
Django帶有一些內建的中間件來處理常見的問題

認證支持中間件
中間件類:django.contrib.auth.middleware.AuthenticationMiddleware
運行認證支持,技術上,該中間件為每個進來的HttpRequest對象添加了表示當前登錄的用戶的request.user屬性
參考第15章得到完整的細節

"Common"中間件
中間件類:django.middleware.common.CommonMiddleware
為完美主義者添加一些方便:
1,禁止訪問在DISALLOWED_USER_AGENTS設置中的user agents,該設置應該是一個字符串列表
2,基于APPEND_SLASH和PREPEND_WWW設置執行URL重定向,如果APPEND_SLASH為True,缺少結尾的斜線的URLs將被重定向到相
同的結尾有斜線的URL,除非路徑中最后的組件包含一個小數點,所以foo.com/bar被重定向到foo.com/bar/,但是foo.com/
bar/file.txt會無更改的傳遞
如果PREPEND_WWW為True,缺少開頭的"www."的URLs將被重定向到相同的有開頭的"www."的URL
這些選項都意味著規范化URLs,哲學是每個URL應該應該存在于一個并且只有一個地方,技術上URL foo.com/bar和foo.com/
bar/不同--搜索引擎索引器將把它們視為不同的URLs,所以規范化URLs是最佳實踐
3,基于USE_ETAGS設置處理ETags,如果USE_ETAGS設置為True,Django將通過MD5-哈希頁面內容為每個請求計算Etag,并且
如果合適的話它將注意發送未修改的應答

壓縮中間件
中間件類:django.middleware.gzip.GZipMiddleware
如果被激活,該中間件將為理解gzip壓縮的瀏覽器(所有的現代瀏覽器)自動壓縮內容
這可以以處理時間為代價很大的減少web服務器消耗的帶寬數量,我們通常選擇速度而不是帶寬,但是如果你想使用相反的一
邊,只需激活該中間件

有條件的GET中間件
中間件類:django.middleware.http.ConditionalGetMiddleware
如果被激活,它提供有條件的GET操作支持,如果應答有一個ETag或者Last-Modified頭部,并請求有If-None-Match或者If-
Modified-Since,應答將被304("未修改")應答替換
它也為所有請求刪除任何應答到HEAD請求的內容并設置Date和Content-Length應答頭部

倒轉代理支持(X-Forwarede-For中間件)
中間件類:django.middleware.http.SetRemoteAddrFromForwaredFor
則是我們上面看到的例子,它基于request.META['HTTP_X_FORWARDED_FOR']設置request.META['REMOTE_ADDR'],如果前者
設置了的話,這當你位于將每個請求的REMOTE_ADDR設置為127.0.0.1的倒轉代理后面時很有用
危險,Will Robinson!
它不驗證HTTP_X_FORWARDED_FOR
如果你沒有在自動設置HTTP_X_FORWARDED_FOR的倒轉代理后面,則不要使用該中間件,任何人都可以欺騙HTTP_X_FORWARDED_
FOR的值,由于它基于HTTP_X_FORWARDED_FOR設置REMOTE_ADDR,這意味著任何人可以偽造他們的IP地址
只有當你可以絕對信任HTTP_X_FORWARDED_FOR的值時使用該中間件

Session支持中間件
中間件類:django.contrib.sessions.middleware.SessionMiddleware
允許session支持,參考第15章的細節

站點寬度緩存中間件
中間件類:django.middleware.cache.CacheMiddleware
如果被激活,每個Django驅動的頁面將被緩存,這在第14章詳細討論了

事務中間件
中間件類:django.middleware.transaction.TransactionMiddleware
在請求/應答階段綁定數據庫COMMIT或者ROLLBACK,如果視圖方法成功運行,則COMMIT完成,如果它以異常失敗,則ROLLBACK
完成
在堆棧中該中間件的順序很重要:運行在它外面的中間件模塊以Django默認行為commit-on-save運行,運行在它里面(在堆棧
中它后面)的中間件模塊將和視圖方法處于同一事務控制
參考XXX來得到更多關于數據庫事務的信息

"X-View"中間件
中間件類:django.middleware.doc.XViewMiddleware
對來自INTERNAL_IPS設置中定義的IP地址的HEAD請求發送自定義X-View HTTP頭部,它被Django的自動文檔系統使用
安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢
主站蜘蛛池模板: 绍兴宇力半导体有限公司官网 | 河北万岁药业有限公司| 在线红外水分测控仪-SK-100水分测试仪-上海拓西电子科技有限公司 | 聚丙烯酰胺,聚合氯化铝,重金属捕捉剂,污泥调理剂,活性氧化铝,生石灰,反渗透阻垢剂,工业葡萄糖,硫酸铝,果壳活性炭,柱状活性炭,蜂窝活性炭,石英砂,锰砂-北京雁归来环保科技有限公司-以真诚为立足之本,以质量为生存之本,愿与海内外同仁共创双赢。雁归来人一路走来,气贯长虹,勇锐盖过怯弱,进取压倒苟安!我们紧扣时代脉搏,专注水处理、继往开来! | 轮转印刷机_商标印唛机_超声波切唛机_瑞安市明辉机械有限公司 | 无锡纯铁-中纯特钢纯铁公司 | 助乐邦轮椅,北京轮椅置换,电动轮椅置换,轮椅回收北京,轮椅送货上门服务 | 硬脂酸钡_硬脂酸镁_硬脂酸镉_硬脂酸铝_硬脂酸锌-石家庄中石恒达矿产品有限公司 | 净化塔_喷淋塔_脱硫塔_河北宝飞华创玻璃钢制造有限公司-河北宝飞华创玻璃钢制造有限公司 | 浙江三龙通用机械有限公司 圆丝机,拉丝机,复合机 | 友信京泰-操作台-调度台-控制台-监控台定制厂家 | 桥梁支座更换_桥梁检测车租赁_高空作业车出租_支座更换_伸缩缝安装_隧道防水_养护加固_维修_出租_衡水庆兴桥梁养护工程有限公司 桥梁养护|桥梁维修加固|隧道裂缝修补|支座更换|管道堵水气囊|衡水众拓路桥养护有限公司 | 数据采集卡_北京科尔特兴业测控技术研究所 | 凿岩机|操车设备|爬车机|三环链|伞钻|伞型钻机|中心回转抓岩机|往复式给煤机|滚轮罐耳|吊桶|钩头-济宁卓力工矿设备有限公司 | 九江江菱电梯有限公司 | 切割片-砂轮片-抛光片-磨片-方格片-百叶片生产厂家定制加工-达蒙砂轮价格优惠 | 内蒙古国际门窗幕墙展览会| 上海律师_上海法律咨询_律师在线咨询网站_上海律师事务所-沪律网 | 箱式电炉,箱式烧结炉,箱式马弗炉,箱式实验炉,高温箱式电阻炉,箱式加热炉,箱式退火炉,箱式真空气氛炉洛阳研博炉业有限公司 | 苏州宣传片制作_企业展厅设计_博物馆设计_展馆设计_方行舟设计公司 | 模具配件加工厂|东莞模具配件加工|模具配件加工厂|精密塑胶模具配件|东莞市优迪精密模具制品有限公司 | 消防工程公司,消防工程承接公司-亿杰(北京)工程安装有限公司 | 武汉不锈钢水箱厂家_武汉不锈钢消防水箱定做批发_武汉不锈钢消防水箱加工厂 | 天天生活网_实用的生活常识网站、有趣的生活点滴小妙招分享 | 烘干机_回转窑_破碎机_制砂机_洗砂机_球磨机-瑞光金属制品 | 石家庄团建公司|石家庄拓展训练|石家庄拓展培训|石家庄公司团建|石家庄拓展公司-石家庄启聚团建公司 | 七评-爱美儿信息科技有限公司〖官网〗?| 实验升降炉-箱式管式炉- 台车真空炉-熔块旋转炉-推板隧道窑-洛阳鲁威窑炉有限公司 | 真空上料机_加料机_天津自动上料机_投料站_包装机加料_吸料机_粉体称重-天津市飞云粉体设备有限公司 | 螺带混合机|卧式螺带混合机|双动力混合机-无锡鑫海干燥粉体设备有限公司 | 景德镇芳然装饰有限公司| 神魔录官网 - 收藏网址的地方,也是防骗小知识分享的地方 | 模具|数控加工-车床加工-精密数控铣床-东莞市方菱精密模具有限公司专注零件及模具加工 | 九江赛璐珞实业有限公司-赛璐珞板,赛璐璐板材,PVC装饰膜,PVC片材,醋酸纤维胶板_多彩装饰材料生产厂家 | 青岛相控阵检测_无损探伤检测机构_相控阵超声检测公司-青岛发现检验技术咨询 | 斜管填料_斜板填料_纤维球_果壳活性炭_立体网状填料_纤维球厂家-巩义市德科净水材料有限公司 | 上海搬运公司_上海工厂设备搬迁_大型设备吊装搬运_设备安装公司-桂星装卸搬运 | 易众拍卖行-事故车拍卖,残值车拍卖,水淹车拍卖,全损车拍卖,修复车拍卖,碰橦车拍卖,瑕疵车拍卖,报废车拍卖,泡水车拍卖,拆车件拍卖,配件拍卖,火烧车拍卖,二手车拍卖专业线上平台 | 印刷包装网_印刷包装_机械设备_行业动态_展会信息 | 消防改造安装,消防维修检测,消防工程安装,气体灭火施工安装,火灾烟感探测器清洗 | 上海慧泰仪器制造有限公司|