The Django Book

Chapter 15: Middleware

cWmJ6g <a href=”http://cyvpcnnnopeh.com/“>cyvpcnnnopeh</a>, [url=http://umnjinbhjnfp.com/]umnjinbhjnfp[/url], [link=http://ogxwkquofrtk.com/]ogxwkquofrtk[/link], http://btunlggosoud.com/

On occasion, youll need to run a piece of code on each and every request that Django handles. This code might need to modify the request before the view handles it, it might need to log information about the request for debugging purposes, and so forth.

鍦ㄦ湁浜涘満鍚堬紝闇瑕佸Django澶勭悊鐨勬瘡涓猺equest閮芥墽琛屾煇娈典唬鐮併傝繖绫讳唬鐮佸彲鑳芥槸鍦╲iew澶勭悊涔嬪墠淇敼浼犲叆鐨剅equest锛屾垨鑰呰褰曟棩蹇椾俊鎭互渚夸簬璋冭瘯锛岀瓑绛夈

You can do this with Djangos middleware framework, which is a set of hooks into Djangos request/response processing. Its a light, low-level plug-in system capable of globally altering both Djangos input and output.

杩欑被鍔熻兘鍙互鐢―jango鐨勪腑闂翠欢妗嗘灦鏉ュ疄鐜帮紝璇ユ鏋剁敱鍒囧叆鍒癉jango鐨剅equest/response澶勭悊杩囩▼涓殑閽╁瓙闆嗗悎缁勬垚銆傝繖涓交閲忕骇浣庡眰娆$殑plug-in绯荤粺锛岃兘鐢ㄤ簬鍏ㄩ潰鐨勪慨鏀笵jango鐨勮緭鍏ュ拰杈撳嚭銆

Each middleware component is responsible for doing some specific function. If youre reading this book linearly (sorry, postmodernists), youve seen middleware a number of times already:

姣忎釜涓棿浠剁粍浠堕兘鐢ㄤ簬鏌愪釜鐗瑰畾鐨勫姛鑳姐傚鏋滈『搴忛槄璇昏繖鏈功(璋ㄥ鍚庣幇浠d富涔夎呰〃绀烘姳姝)锛屼綘鍙兘宸茬粡澶氭鐪嬪埌涓棿浠朵簡:

  • All of the session and user tools that we looked at in Chapter 12 are made possible by a few small pieces of middleware (more specifically, the middleware makes request.session and request.user available to you in views).

  • 绗12绔犱腑鎵鏈夌殑session鍜寀ser宸ュ叿閮界睄鐢变竴灏忕皣涓棿浠跺疄鐜(渚嬪锛岀敱涓棿浠惰瀹歷iew涓彲瑙佺殑 request.sessionrequest.user )銆

  • The sitewide cache discussed in Chapter 13 is actually just a piece of middleware that bypasses the call to your view function if the response for that view has already been cached.

  • 绗13绔犺璁虹殑绔欑偣鑼冨洿cache瀹為檯涓婁篃鏄敱涓涓腑闂翠欢瀹炵幇锛屼竴鏃﹁涓棿浠跺彂鐜颁笌view鐩稿簲鐨剅esponse宸插湪缂撳瓨涓紝灏变笉鍐嶈皟鐢ㄥ搴旂殑view鍑芥暟銆

  • The flatpages , redirects , and csrf contributed applications from Chapter 14 all do their magic through middleware components.

RqRk8H <a href=”http://ercrrxdpamvi.com/“>ercrrxdpamvi</a>, [url=http://zgnluiwplwwn.com/]zgnluiwplwwn[/url], [link=http://iwcntomqptnu.com/]iwcntomqptnu[/link], http://birfusxixxbq.com/

This chapter dives deeper into exactly what middleware is and how it works, and explains how you can write your own middleware.

杩欎竴绔犲皢娣卞叆鍒颁腑闂翠欢鍙婂叾宸ヤ綔鏈哄埗涓紝骞堕槓杩板浣曡嚜琛岀紪鍐欎腑闂翠欢銆

Whats Middleware?

JngVYk <a href=”http://djvmxufesoab.com/“>djvmxufesoab</a>, [url=http://irwppoluxxlu.com/]irwppoluxxlu[/url], [link=http://hkktedgxtjnq.com/]hkktedgxtjnq[/link], http://ambemukzdulf.com/

A middleware component is simply a Python class that conforms to a certain API. Before diving into the formal aspects of what that API is, lets look at a very simple example.

涓棿浠剁粍浠舵槸閬靛惊鐗瑰畾API瑙勫垯鐨勭畝鍗昉ython绫汇傚湪娣卞叆鍒拌API瑙勫垯鐨勬寮忕粏鑺備箣鍓嶏紝鍏堢湅涓涓嬩笅闈㈣繖涓潪甯哥畝鍗曠殑渚嬪瓙銆

High-traffic sites often need to deploy Django behind a load-balancing proxy (see Chapter 20). This can cause a few small complications, one of which is that every requests remote IP (request.META["REMOTE_IP"] ) will be that of the load balancer, not the actual IP making the request. Load balancers deal with this by setting a special header, X-Forwarded-For , to the actual requesting IP address.

楂樻祦閲忕殑绔欑偣閫氬父闇瑕佸皢Django閮ㄧ讲鍦ㄨ礋杞藉钩琛roxy(鍙傝绗20绔)涔嬪悗銆傝繖绉嶆柟寮忓皢甯︽潵涓浜涘鏉傛э紝鍏朵竴灏辨槸姣忎釜request涓殑杩滅▼IP鍦板潃(request.META["REMOTE_IP"])灏嗘寚鍚戣璐熻浇骞宠 proxy锛岃屼笉鏄彂璧疯繖涓猺equest鐨勫疄闄匢P銆傝礋杞藉钩琛roxy澶勭悊杩欎釜闂鐨勬柟娉曞湪鐗规畩鐨 X-Forwarded-For 涓缃疄闄呭彂璧疯姹傜殑IP銆

So heres a small bit of middleware that lets sites running behind a proxy still see the correct IP address in request.META["REMOTE_ADDR"] :

es5yV3 <a href=”http://qujmqpdlocgp.com/“>qujmqpdlocgp</a>, [url=http://wwhfusjoejpl.com/]wwhfusjoejpl[/url], [link=http://tadhllijhhfv.com/]tadhllijhhfv[/link], http://kckmxarvaboc.com/

class SetRemoteAddrFromForwardedFor(object):
    def process_request(self, request):
        try:
            real_ip = request.META['HTTP_X_FORWARDED_FOR']
        except KeyError:
            pass
        else:
            # HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs.
            # Take just the first one.
            real_ip = real_ip.split(",")[0]
            request.META['REMOTE_ADDR'] = real_ip

If this is installed (see the next section), every requests X-Forwarded-For value will be automatically inserted into request.META['REMOTE_ADDR'] . This means your Django applications dont need to be concerned with whether theyre behind a load-balancing proxy or not; they can simply access request.META['REMOTE_ADDR'] , and that will work whether or not a proxy is being used.

涓鏃﹀畨瑁呬簡璇ヤ腑闂翠欢(鍙傝涓嬩竴鑺)锛屾瘡涓猺equest涓殑 X-Forwarded-For 鍊奸兘浼氳鑷姩鎻掑叆鍒 request.META['REMOTE_ADDR'] 涓傝繖鏍凤紝Django搴旂敤灏变笉闇瑕佸叧蹇冭嚜宸辨槸鍚︿綅浜庤礋杞藉钩琛roxy涔嬪悗锛涚畝鍗曡鍙 request.META['REMOTE_ADDR'] 鐨勬柟寮忓湪鏄惁鏈塸roxy鐨勬儏褰笅閮藉皢姝e父宸ヤ綔銆

In fact, this is a common enough need that this piece of middleware is a built-in part of Django. It lives in django.middleware.http , and you can read a bit more about it in the next section.

瀹為檯涓婏紝涓洪拡瀵硅繖涓潪甯稿父瑙佺殑鎯呭舰锛孌jango宸插皢璇ヤ腑闂翠欢鍐呯疆銆傚畠浣嶄簬 django.middleware.http 涓, 涓嬩竴鑺傚皢缁欏嚭杩欎釜涓棿浠剁浉鍏崇殑鏇村缁嗚妭銆

Middleware Installation

瀹夎涓棿浠

If youve read this book straight through, youve already seen a number of examples of middleware installation; many of the examples in previous chapters have required certain middleware. For completeness, heres how to install middleware.

濡傛灉鎸夐『搴忛槄璇绘湰涔︼紝搴斿綋宸茬粡鐪嬪埌娑夊強鍒颁腑闂翠欢瀹夎鐨勫涓ず渚,鍥犱负鍓嶉潰绔犺妭鐨勮澶氫緥瀛愰兘闇瑕佹煇浜涚壒瀹氱殑涓棿浠躲傚嚭浜庡畬鏁存ц冭檻锛屼笅闈粙缁嶅浣曞畨瑁呬腑闂翠欢銆

To activate a middleware component, add it to the MIDDLEWARE_CLASSES tuple in your settings module. In MIDDLEWARE_CLASSES , each middleware component is represented by a string: the full Python path to the middlewares class name. For example, heres the default MIDDLEWARE_CLASSES created by django-admin.py startproject :

hA1uWo <a href=”http://tbiqmlhmsarl.com/“>tbiqmlhmsarl</a>, [url=http://ycmmwmnthoqr.com/]ycmmwmnthoqr[/url], [link=http://tnpdbjabjixm.com/]tnpdbjabjixm[/link], http://kjgixidgzotv.com/

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.doc.XViewMiddleware'
)

A Django installation doesnt require any middleware MIDDLEWARE_CLASSES can be empty, if youd like but we recommend that you activate CommonMiddleware , which we explain shortly.

Django椤圭洰鐨勫畨瑁呭苟涓嶅己鍒惰姹備换浣曚腑闂翠欢锛屽鏋滀綘鎰挎剰锛 MIDDLEWARE_CLASSES 鍙互涓虹┖銆備絾鎴戜滑寤鸿鍚敤 CommonMiddleware 锛岀◢鍚庡仛鍑鸿В閲娿

The order is significant. On the request and view phases, Django applies middleware in the order given in MIDDLEWARE_CLASSES , and on the response and exception phases, Django applies middleware in reverse order. That is, Django treats MIDDLEWARE_CLASSES as a sort of wrapper around the view function: on the request it walks down the list to the view, and on the response it walks back up. See the section How Django Processes a Request: Complete Details in Chapter 3 for a review of the phases.

杩欓噷涓棿浠跺嚭鐜扮殑椤哄簭闈炲父閲嶈銆傚湪request鍜寁iew鐨勫鐞嗛樁娈碉紝Django鎸夌収 MIDDLEWARE_CLASSES 涓嚭鐜扮殑椤哄簭鏉ュ簲鐢ㄤ腑闂翠欢锛岃屽湪response鍜屽紓甯稿鐞嗛樁娈碉紝Django鍒欐寜閫嗗簭鏉ヨ皟鐢ㄥ畠浠備篃灏辨槸璇达紝Django灏 MIDDLEWARE_CLASSES 瑙嗕负view鍑芥暟澶栧眰鐨勯『搴忓寘瑁呭瓙锛氬湪request闃舵鎸夐『搴忎粠涓婂埌涓嬬┛杩囷紝鑰屽湪response鍒欏弽杩囨潵銆傚叧浜嶥jango澶勭悊闃舵鐨勮缁嗕俊鎭紝璇峰弬瑙佺涓夌珷”Django鎬庝箞澶勭悊涓涓姹: 瀹屾暣缁嗚妭”杩欎竴鑺傘

Middleware Methods

涓棿浠舵柟娉

Now that you know what middleware is and how to install it, lets take a look at all the available methods that middleware classes can define.

鐜板湪锛屾垜浠凡缁忕煡閬撲粈涔堟槸涓棿浠跺拰鎬庝箞瀹夎瀹冿紝涓嬮潰灏嗕粙缁嶄腑闂翠欢绫讳腑鍙互瀹氫箟鐨勬墍鏈夋柟娉曘

Initializer: __init__(self)

Initializer: __init__(self)

Use __init__() to perform systemwide setup for a given middleware class.

鍦ㄤ腑闂翠欢绫讳腑锛 __init__() 鏂规硶鐢ㄤ簬鎵ц绯荤粺鑼冨洿鐨勮缃

For performance reasons, each activated middleware class is instantiated only once per server process. This means that __init__() is called only once at server startup not for individual requests.

鍑轰簬鎬ц兘鐨勮冭檻锛屾瘡涓凡鍚敤鐨勪腑闂翠欢鍦ㄦ瘡涓湇鍔″櫒杩涚▼涓彧鍒濆鍖 娆°備篃灏辨槸璇 __init__() 浠呭湪鏈嶅姟杩涚▼鍚姩鐨勬椂鍊欒皟鐢紝鑰屽湪閽堝鍗曚釜request澶勭悊鏃跺苟涓嶆墽琛屻

A common reason to implement an __init__() method is to check whether the middleware is indeed needed. If __init__() raises django.core.exceptions.MiddlewareNotUsed , then Django will remove the middleware from the middleware stack. You might use this feature to check for some piece of software that the middleware class requires, or check whether the server is running debug mode, or any other such environment situation.

瀵逛竴涓猰iddleware鑰岃█锛屽畾涔 __init__() 鏂规硶鐨勯氬父鍘熷洜鏄鏌ヨ嚜韬殑蹇呰鎬с傚鏋 __init__() 鎶涘嚭寮傚父 django.core.exceptions.MiddlewareNotUsed ,鍒橠jango灏嗕粠middleware鏍堜腑绉诲嚭璇iddleware銆傚彲浠ョ敤杩欎釜鏈哄埗鏉ユ鏌iddleware渚濊禆鐨勮蒋浠舵槸鍚﹀瓨鍦ㄣ佹湇鍔℃槸鍚﹁繍琛屼簬璋冭瘯妯″紡銆佷互鍙婁换浣曞叾瀹冪幆澧冨洜绱犮

If a middleware class defines an __init__() method, the method should take no arguments beyond the standard self .

鍦ㄤ腑闂翠欢涓畾涔 __init__() 鏂规硶鏃讹紝闄や簡鏍囧噯鐨 self 鍙傛暟涔嬪锛屼笉搴斿畾涔変换浣曞叾瀹冨弬鏁般

Request Preprocessor: process_request(self, request)

Request棰勫鐞嗗嚱鏁: process_request(self, request)

This method gets called as soon as the request has been received before Django has parsed the URL to determine which view to run. It gets passed the HttpRequest object, which you may modify at will.

杩欎釜鏂规硶鐨勮皟鐢ㄦ椂鏈哄湪Django鎺ユ敹鍒皉equest涔嬪悗锛屼絾浠嶆湭瑙f瀽URL浠ョ‘瀹氬簲褰撹繍琛岀殑view涔嬪墠銆侱jango鍚戝畠浼犲叆鐩稿簲鐨 HttpRequest 瀵硅薄锛屼互渚垮湪鏂规硶涓慨鏀广

process_request() should return either None or an HttpResponse object.

process_request() 搴斿綋杩斿洖 NoneHttpResponse 瀵硅薄.

  • If it returns None , Django will continue processing this request, executing any other middleware and then the appropriate view.

9y6EAY <a href=”http://ghipvqxmhbgk.com/“>ghipvqxmhbgk</a>, [url=http://mdtqthuugucf.com/]mdtqthuugucf[/url], [link=http://oowalnqibcdm.com/]oowalnqibcdm[/link], http://sidafqbzawbf.com/

  • If it returns an HttpResponse object, Django wont bother calling any other middleware (of any type) or the appropriate view. Django will immediately return that HttpResponse .

  • 濡傛灉杩斿洖 HttpResponse 瀵硅薄, Django 灏嗕笉鍐嶆墽琛 浠讳綍 鍏跺畠鐨勪腑闂翠欢(鑰屾棤瑙嗗叾绉嶇被)浠ュ強鐩稿簲鐨剉iew銆 Django灏嗙珛鍗宠繑鍥炶 HttpResponse .

View Preprocessor: process_view(self, request, view, args, kwargs)

View棰勫鐞嗗嚱鏁: process_view(self, request, view, args, kwargs)

This method gets called after the request preprocessor is called and Django has determined which view to execute, but before that view has actually been executed.

杩欎釜鏂规硶鐨勮皟鐢ㄦ椂鏈哄湪Django鎵ц瀹宺equest棰勫鐞嗗嚱鏁板苟纭畾寰呮墽琛岀殑view涔嬪悗锛屼絾鍦╲iew鍑芥暟瀹為檯鎵ц涔嬪墠銆

The arguments passed to this view are shown in Table 15-1.

琛15-1鍒楀嚭浜嗕紶鍏ュ埌杩欎釜View棰勫鐞嗗嚱鏁扮殑鍙傛暟銆

Table 15-1. Arguments Passed to process_view()
Argument Explanation
request The HttpRequest object.
view The Python function that Django will call to handle this request. This is the actual function object itself, not the name of the function as a string.
args The list of positional arguments that will be passed to the view, not including the request argument (which is always the first argument to a view).
kwargs The dictionary of keyword arguments that will be passed to the view.

SoSjGG <a href=”http://yiqzndzralaf.com/“>yiqzndzralaf</a>, [url=http://gjemutbubtxu.com/]gjemutbubtxu[/url], [link=http://zgdgecnxtllq.com/]zgdgecnxtllq[/link], http://gtldsopsugix.com/

Just like process_request() , process_view() should return either None or an HttpResponse object.

濡傚悓 process_request() , process_view() 搴斿綋杩斿洖 NoneHttpResponse 瀵硅薄銆

  • If it returns None , Django will continue processing this request, executing any other middleware and then the appropriate view.

  • 濡傛灉杩斿洖 None , Django灏嗙户缁鐞嗚繖涓 request ,鎵ц鍚庣画鐨勪腑闂翠欢锛 鐒跺悗璋冪敤鐩稿簲鐨剉iew.

  • If it returns an HttpResponse object, Django wont bother calling any other middleware (of any type) or the appropriate view. Django will immediately return that HttpResponse .

  • 濡傛灉杩斿洖 HttpResponse 瀵硅薄, Django 灏嗕笉鍐嶆墽琛 浠讳綍 鍏跺畠鐨勪腑闂翠欢(涓嶈绉嶇被)浠ュ強鐩稿簲鐨剉iew. Django灏嗙珛鍗宠繑鍥炶 HttpResponse .

Response Postprocessor: process_response(self, request, response)

Response鍚庡鐞嗗嚱鏁: process_response(self, request, response)

This method gets called after the view function is called and the response is generated. Here, the processor can modify the content of a response; one obvious use case is content compression, such as gzipping of the requests HTML.

杩欎釜鏂规硶鐨勮皟鐢ㄦ椂鏈哄湪Django鎵цview鍑芥暟骞剁敓鎴恟esponse涔嬪悗銆傝繖閲岋紝璇ュ鐞嗗櫒灏辫兘淇敼response鐨勫唴瀹癸紱涓涓父瑙佺殑鐢ㄩ旀槸鍐呭鍘嬬缉锛屽gzip鎵璇锋眰鐨凥TML椤甸潰銆

The parameters should be pretty self-explanatory: request is the request object, and response is the response object returned from the view.

2757R8 <a href=”http://ndxancnqdyvt.com/“>ndxancnqdyvt</a>, [url=http://hewnhomongfc.com/]hewnhomongfc[/url], [link=http://bvxaqxmjctkj.com/]bvxaqxmjctkj[/link], http://bwjtrsshemnb.com/

Unlike the request and view preprocessors, which may return None , process_response() must return an HttpResponse object. That response could be the original one passed into the function (possibly modified) or a brand-new one.

涓嶅悓鍙兘杩斿洖 None 鐨剅equest鍜寁iew棰勫鐞嗗嚱鏁, process_response() 蹇呴』 杩斿洖 HttpResponse 瀵硅薄. 杩欎釜response瀵硅薄鍙互鏄紶鍏ュ嚱鏁扮殑閭d竴涓師濮嬪璞(閫氬父宸茶淇敼)锛屼篃鍙互鏄叏鏂扮敓鎴愮殑銆

Exception Postprocessor: process_exception(self, request, exception)

Exception鍚庡鐞嗗嚱鏁: process_exception(self, request, exception)

This method gets called only if something goes wrong and a view raises an uncaught exception. You can use this hook to send error notifications, dump postmortem information to a log, or even try to recover from the error automatically.

杩欎釜鏂规硶鍙湁鍦╮equest澶勭悊杩囩▼涓嚭浜嗛棶棰樺苟涓攙iew鍑芥暟鎶涘嚭浜嗕竴涓湭鎹曡幏鐨勫紓甯告椂鎵嶄細琚皟鐢ㄣ傝繖涓挬瀛愬彲浠ョ敤鏉ュ彂閫侀敊璇氱煡锛屽皢鐜板満鐩稿叧淇℃伅杈撳嚭鍒版棩蹇楁枃浠, 鎴栬呯敋鑷冲皾璇曚粠閿欒涓嚜鍔ㄦ仮澶嶃

The parameters to this function are the same request object weve been dealing with all along, and exception , which is the actual Exception object raised by the view function.

GthFoH <a href=”http://rjaffpesmguf.com/“>rjaffpesmguf</a>, [url=http://drvpmxdwnadz.com/]drvpmxdwnadz[/url], [link=http://wfjwhmeffwjd.com/]wfjwhmeffwjd[/link], http://jzqcmcoorwyq.com/

process_exception() should return a either None or an HttpResponse object.

process_exception() 搴斿綋杩斿洖 None 鎴 HttpResponse 瀵硅薄.

  • If it returns None , Django will continue processing this request with the frameworks built-in exception handling.

  • 濡傛灉杩斿洖 None , Django灏嗙敤妗嗘灦鍐呯疆鐨勫紓甯稿鐞嗘満鍒剁户缁鐞嗙浉搴攔equest銆

  • If it returns an HttpResponse object, Django will use that response instead of the frameworks built-in exception handling.

  • 濡傛灉杩斿洖 HttpResponse 瀵硅薄, Django 灏嗕娇鐢ㄨresponse瀵硅薄锛岃岀煭璺鏋跺唴缃殑寮傚父澶勭悊鏈哄埗銆

Note

澶囨敞

Django ships with a number of middleware classes (discussed in the following section) that make good examples. Reading the code for them should give you a good feel for the power of middleware.

Django鑷甫浜嗙浉褰撴暟閲忕殑涓棿浠剁被(灏嗗湪闅忓悗绔犺妭浠嬬粛)锛屽畠浠兘鏄浉褰撳ソ鐨勮寖渚嬨傞槄璇昏繖浜涗唬鐮佸皢浣夸綘瀵逛腑闂翠欢鐨勫己澶ф湁涓涓緢濂界殑璁よ瘑銆

You can also find a number of community-contributed examples on Djangos wiki: http://code.djangoproject.com/wiki/ContributedMiddleware

鍦―jangos wiki涓婁篃鍙互鎵惧埌澶ч噺鐨勭ぞ鍖鸿础鐚殑涓棿浠惰寖渚: http://code.djangoproject.com/wiki/ContributedMiddleware

Built-in Middleware

鍐呯疆鐨勪腑闂翠欢

Django comes with some built-in middleware to deal with common problems, which we discuss in the sections that follow.

Django鑷甫鑻ュ共鍐呯疆涓棿浠朵互澶勭悊甯歌闂锛屽皢浠庝笅涓鑺傚紑濮嬭璁恒

Authentication Support Middleware

璁よ瘉鏀寔涓棿浠

Middleware class: django.contrib.auth.middleware.AuthenticationMiddleware .

涓棿浠剁被: django.contrib.auth.middleware.AuthenticationMiddleware .

This middleware enables authentication support. It adds the request.user attribute, representing the currently logged-in user, to every incoming HttpRequest object.

wSOx5R <a href=”http://hztnqpaboavm.com/“>hztnqpaboavm</a>, [url=http://vmvmmjrsqxic.com/]vmvmmjrsqxic[/url], [link=http://sngrfxoajwdo.com/]sngrfxoajwdo[/link], http://eautnmbfurjc.com/

See Chapter 12 for complete details.

瀹屾暣鐨勭粏鑺傝鍙傝绗12绔犮

Common Middleware

SP3df8 <a href=”http://bfqhoouwrdmm.com/“>bfqhoouwrdmm</a>, [url=http://hzujzeyighho.com/]hzujzeyighho[/url], [link=http://mbrgpoykhljx.com/]mbrgpoykhljx[/link], http://qqgcbhgtklwg.com/

Middleware class: django.middleware.common.CommonMiddleware .

mBh1AN <a href=”http://vmlyatgebrhc.com/“>vmlyatgebrhc</a>, [url=http://dvatqsqhoxsu.com/]dvatqsqhoxsu[/url], [link=http://zuchupmuwhub.com/]zuchupmuwhub[/link], http://mxgkuqikazko.com/

This middleware adds a few conveniences for perfectionists:

杩欎釜涓棿浠朵负瀹岀編涓讳箟鑰呮彁渚涗簡涓浜涗究鍒:

Forbids access to user agents in the ``DISALLOWED_USER_AGENTS`` setting : If provided, this setting should be a list of compiled regular expression objects that are matched against the user-agent header for each incoming request. Heres an example snippet from a settings file:

绂佹 ``DISALLOWED_USER_AGENTS`` 鍒楄〃涓墍璁剧疆鐨剈ser agent璁块棶 锛氫竴鏃︽彁渚涳紝杩欎竴鍒楄〃搴斿綋鐢卞凡缂栬瘧鐨勬鍒欒〃杈惧紡瀵硅薄缁勬垚锛岃繖浜涘璞$敤浜庡尮閰嶄紶鍏ョ殑request璇锋眰澶翠腑鐨剈ser-agent鍩熴備笅闈㈣繖涓緥瀛愭潵鑷煇涓厤缃枃浠剁墖娈碉細

import re

DISALLOWED_USER_AGENTS = (
    re.compile(r'^OmniExplorer_Bot'),
    re.compile(r'^Googlebot')
)

Note the import re , because DISALLOWED_USER_AGENTS requires its values to be compiled regexes (i.e., the output of re.compile() ). The settings file is regular python, so its perfectly OK to include Python import statements in it.

璇锋敞鎰 import re ,鍥犱负 DISALLOWED_USER_AGENTS 瑕佹眰鍏跺间负宸茬紪璇戠殑姝e垯琛ㄨ揪寮(涔熷氨鏄 re.compile() 鐨勮繑鍥炲)銆傞厤缃枃浠舵槸甯歌鐨刾ython鏂囦欢锛屾墍浠ュ湪鍏朵腑鍖呮嫭Python import 璇彞涓嶄細鏈変换浣曢棶棰樸

Performs URL rewriting based on the ``APPEND_SLASH`` and ``PREPEND_WWW`` settings : If APPEND_SLASH is True , URLs that lack a trailing slash will be redirected to the same URL with a trailing slash, unless the last component in the path contains a period. So foo.com/bar is redirected to foo.com/bar/ , but foo.com/bar/file.txt is passed through unchanged.

渚濇嵁 ``APPEND_SLASH`` 鍜 ``PREPEND_WWW`` 鐨勮缃墽琛孶RL閲嶅啓 锛氬鏋 APPEND_SLASHTrue , 閭d簺灏鹃儴娌℃湁鏂滄潬鐨刄RL灏嗚閲嶅畾鍚戝埌娣诲姞浜嗘枩鏉犵殑鐩稿簲URL锛岄櫎闈瀙ath鐨勬渶鏈粍鎴愰儴鍒嗗寘鍚偣鍙枫傚洜姝わ紝 foo.com/bar 浼氳閲嶅畾鍚戝埌 foo.com/bar/ , 浣嗘槸 foo.com/bar/file.txt 灏嗕互涓嶅彉褰㈠紡閫氳繃銆

If PREPEND_WWW is True , URLs that lack a leading www. will be redirected to the same URL with a leading www..

濡傛灉 PREPEND_WWW 涓 True , 閭d簺缂哄皯鍏堝www.鐨刄RLs灏嗕細琚噸瀹氬悜鍒板惈鏈夊厛瀵紈ww.鐨勭浉搴擴RL涓娿

Both of these options are meant to normalize URLs. The philosophy is that each URL should exist in one and only one place. Technically the URL example.com/bar is distinct from example.com/bar/ , which in turn is distinct from www.example.com/bar/ . A search-engine indexer would treat these as separate URLs, which is detrimental to your sites search-engine rankings, so its a best practice to normalize URLs.

杩欎袱涓夐」閮芥槸涓轰簡瑙勮寖鍖朥RL銆傚叾鍚庣殑鍝插鏄瘡涓猆RL閮藉簲涓斿彧搴斿綋瀛樺湪浜庝竴澶勩傛妧鏈笂鏉ヨ锛孶RL example.com/barexample.com/bar/www.example.com/bar/ 閮戒簰涓嶇浉鍚屻傛悳绱㈠紩鎿庣紪鐩▼搴忓皢鎶婂畠浠涓轰笉鍚岀殑URL,杩欏皢涓嶅埄浜庤绔欑偣鐨勬悳绱㈠紩鎿庢帓鍚嶏紝鍥犳杩欓噷鐨勬渶浣冲疄璺垫槸灏哢RL瑙勮寖鍖栥

Handles ETags based on the ``USE_ETAGS`` setting : ETags are an HTTP-level optimization for caching pages conditionally. If USE_ETAGS is set to True , Django will calculate an ETag for each request by MD5-hashing the page content, and it will take care of sending Not Modified responses, if appropriate.

渚濇嵁 ``USE_ETAGS`` 鐨勮缃鐞咵tag : ETags 鏄疕TTP绾у埆涓婃寜鏉′欢缂撳瓨椤甸潰鐨勪紭鍖栨満鍒躲傚鏋 USE_ETAGSTrue 锛孌jango閽堝姣忎釜璇锋眰浠D5绠楁硶澶勭悊椤甸潰鍐呭锛屼粠鑰屽緱鍒癊tag, 鍦ㄦ鍩虹涓婏紝Django灏嗗湪閫傚綋鎯呭舰涓嬪鐞嗗苟杩斿洖 Not Modified 鍥炲簲(璇戞敞锛氭垨鑰呰缃畆esponse澶翠腑鐨凟tag鍩)銆

Note there is also a conditional GET middleware, covered shortly, which handles ETags and does a bit more.

vhRrpn <a href=”http://zakebgoodhir.com/“>zakebgoodhir</a>, [url=http://qkouvebyetpa.com/]qkouvebyetpa[/url], [link=http://vmzymxxpqwbz.com/]vmzymxxpqwbz[/link], http://aujcfnxghsnw.com/

Compression Middleware

鍘嬬缉涓棿浠

Middleware class: django.middleware.gzip.GZipMiddleware .

涓棿浠剁被: django.middleware.gzip.GZipMiddleware .

This middleware automatically compresses content for browsers that understand gzip compression (all modern browsers). This can greatly reduce the amount of bandwidth a Web server consumes. The tradeoff is that it takes a bit of processing time to compress pages.

杩欎釜涓棿浠惰嚜鍔ㄤ负鑳藉鐞唃zip鍘嬬缉(鍖呮嫭鎵鏈夌殑鐜颁唬娴忚鍣)鐨勬祻瑙堝櫒鑷姩鍘嬬缉杩斿洖]鍐呭銆傝繖灏嗘瀬澶у湴鍑忓皯Web鏈嶅姟鍣ㄦ墍鑰楃敤鐨勫甫瀹姐備唬浠锋槸鍘嬬缉椤甸潰闇瑕佷竴浜涢澶栫殑澶勭悊鏃堕棿銆

We usually prefer speed over bandwidth, but if you prefer the reverse, just enable this middleware.

鐩稿浜庡甫瀹斤紝浜轰滑涓鑸洿闈掔潗浜庨熷害锛屼絾鏄鏋滀綘鐨勬儏褰㈡濂界浉鍙嶏紝灏藉彲鍚敤杩欎釜涓棿浠躲

Conditional GET Middleware

鏉′欢鍖栫殑GET涓棿浠

Middleware class: django.middleware.http.ConditionalGetMiddleware .

涓棿浠剁被: django.middleware.http.ConditionalGetMiddleware .

This middleware provides support for conditional GET operations. If the response has an Last-Modified or ETag or header, and the request has If-None-Match or If-Modified-Since , the response is replaced by an 304 (Not modified) response. ETag support depends on on the USE_ETAGS setting and expects the ETag response header to already be set. As discussed above, the ETag header is set by the Common middleware.

杩欎釜涓棿浠跺鏉′欢鍖 GET 鎿嶄綔鎻愪緵鏀寔銆傚鏋渞esponse澶翠腑鍖呮嫭 Last-ModifiedETag 鍩燂紝骞朵笖request澶翠腑鍖呭惈 If-None-MatchIf-Modified-Since 鍩燂紝涓斾袱鑰呬竴鑷达紝鍒欒response灏嗚response 304(Not modified)鍙栦唬銆傚 ETag 鐨勬敮鎸佷緷璧栦簬 USE_ETAGS 閰嶇疆鍙婁簨鍏堝湪response澶翠腑璁剧疆 ETag 鍩熴傜◢鍓嶆墍璁ㄨ鐨勯氱敤涓棿浠跺彲鐢ㄤ簬璁剧疆response涓殑 ETag 鍩熴

It also removes the content from any response to a HEAD request and sets the Date and Content-Length response headers for all requests.

姝ゅ锛屽畠涔熷皢鍒犻櫎澶勭悊 HEAD request鏃舵墍鐢熸垚鐨剅esponse涓殑浠讳綍鍐呭锛屽苟鍦ㄦ墍鏈塺equest鐨剅esponse澶翠腑璁剧疆 DateContent-Length 鍩熴

Reverse Proxy Support (X-Forwarded-For Middleware)

鍙嶅悜浠g悊鏀寔 (X-Forwarded-For涓棿浠)

Middleware class: django.middleware.http.SetRemoteAddrFromForwardedFor .

涓棿浠剁被: django.middleware.http.SetRemoteAddrFromForwardedFor .

This is the example we examined in the Whats Middleware? section earlier. It sets request.META['REMOTE_ADDR'] based on request.META['HTTP_X_FORWARDED_FOR'] , if the latter is set. This is useful if youre sitting behind a reverse proxy that causes each requests REMOTE_ADDR to be set to 127.0.0.1 .

杩欐槸鎴戜滑鍦 浠涔堟槸涓棿浠 杩欎竴鑺備腑鎵涓剧殑渚嬪瓙銆 鍦 request.META['HTTP_X_FORWARDED_FOR'] 瀛樺湪鐨勫墠鎻愪笅锛屽畠鏍规嵁鍏跺兼潵璁剧疆 request.META['REMOTE_ADDR'] 銆傚湪绔欑偣浣嶄簬鏌愪釜鍙嶅悜浠g悊涔嬪悗鐨勩佹瘡涓猺equest鐨 REMOTE_ADDR 閮借鎸囧悜 127.0.0.1 鐨勬儏褰笅锛岃繖涓鍔熻兘灏嗛潪甯告湁鐢ㄣ

Danger!

绾㈣壊璀﹀憡锛

This middleware does not validate HTTP_X_FORWARDED_FOR .

杩欎釜middleware骞 楠岃瘉 HTTP_X_FORWARDED_FOR 鐨勫悎娉曟с

If youre not behind a reverse proxy that sets HTTP_X_FORWARDED_FOR automatically, do not use this middleware. Anybody can spoof the value of HTTP_X_FORWARDED_FOR , and because this sets REMOTE_ADDR based on HTTP_X_FORWARDED_FOR , that means anybody can fake his IP address.

濡傛灉绔欑偣骞朵笉浣嶄簬鑷姩璁剧疆 HTTP_X_FORWARDED_FOR 鐨勫弽鍚戜唬鐞嗕箣鍚庯紝璇蜂笉瑕佷娇鐢ㄨ繖涓腑闂翠欢銆傚惁鍒欙紝鍥犱负浠讳綍浜洪兘鑳藉浼 HTTP_X_FORWARDED_FOR 鍊硷紝鑰 REMOTE_ADDR 鍙堟槸渚濇嵁 HTTP_X_FORWARDED_FOR 鏉ヨ缃紝杩欏氨鎰忓懗鐫浠讳綍浜洪兘鑳藉浼營P鍦板潃銆

Only use this middleware when you can absolutely trust the value of HTTP_X_FORWARDED_FOR .

OWMO5w <a href=”http://nzgilwohijwo.com/“>nzgilwohijwo</a>, [url=http://hfkdfsayubmc.com/]hfkdfsayubmc[/url], [link=http://mgxuxjsucdhb.com/]mgxuxjsucdhb[/link], http://mnuxwagwigkb.com/

Session Support Middleware

浼氳瘽鏀寔涓棿浠

Middleware class: django.contrib.sessions.middleware.SessionMiddleware .

涓棿浠剁被: django.contrib.sessions.middleware.SessionMiddleware .

This middleware enables session support. See Chapter 12 for details.

杩欎釜涓棿浠舵縺娲讳細璇濇敮鎸佸姛鑳. 缁嗚妭璇峰弬瑙佺12绔犮

Sitewide Cache Middleware

绔欑偣缂撳瓨涓棿浠

Middleware class: django.middleware.cache.CacheMiddleware .

ZV3FvR <a href=”http://haiujfhxgmcm.com/“>haiujfhxgmcm</a>, [url=http://nvlhddespdgs.com/]nvlhddespdgs[/url], [link=http://siljtaebxpgm.com/]siljtaebxpgm[/link], http://vlrjbtvuqedl.com/

This middleware caches each Django-powered page. This was discussed in detail in Chapter 13.

杩欎釜涓棿浠剁紦瀛楧jango澶勭悊鐨勬瘡涓〉闈€傚凡鍦ㄧ13绔犱腑璇︾粏璁ㄨ銆

Transaction Middleware

浜嬪姟澶勭悊涓棿浠

Middleware class: django.middleware.transaction.TransactionMiddleware .

涓棿浠剁被: django.middleware.transaction.TransactionMiddleware .

This middleware binds a database COMMIT or ROLLBACK to the request/response phase. If a view function runs successfully, a COMMIT is issued. If the view raises an exception, a ROLLBACK is issued.

杩欎釜涓棿浠跺皢鏁版嵁搴撶殑 COMMITROLLBACK 缁戝畾鍒皉equest/response澶勭悊闃舵銆傚鏋渧iew鍑芥暟鎴愬姛鎵ц锛屽垯鍙戝嚭 COMMIT 鎸囦护銆傚鏋渧iew鍑芥暟鎶涘嚭寮傚父锛屽垯鍙戝嚭 ROLLBACK 鎸囦护銆

The order of this middleware in the stack is important. Middleware modules running outside of it run with commit-on-save the default Django behavior. Middleware modules running inside it (coming later in the stack) will be under the same transaction control as the view functions.

杩欎釜涓棿浠跺湪鏍堜腑鐨勯『搴忛潪甯搁噸瑕併傚叾澶栧眰鐨勪腑闂翠欢妯″潡杩愯鍦―jango缂虹渷鐨 淇濆瓨-鎻愪氦 琛屼负妯″紡涓嬨傝屽叾鍐呭眰涓棿浠(鍦ㄦ爤涓殑鍏跺悗浣嶇疆鍑虹幇)灏嗙疆浜庝笌view鍑芥暟涓鑷寸殑浜嬪姟鏈哄埗鐨勬帶鍒朵笅銆

See Appendix C for more about information about database transactions.

鍏充簬鏁版嵁搴撲簨鍔″鐞嗙殑鏇村淇℃伅锛岃鍙傝闄勫綍C銆

X-View Middleware

X-View 涓棿浠

Middleware class: django.middleware.doc.XViewMiddleware .

涓棿浠剁被: django.middleware.doc.XViewMiddleware .

This middleware sends custom X-View HTTP headers to HEAD requests that come from IP addresses defined in the INTERNAL_IPS setting. This is used by Djangos automatic documentation system.

杩欎釜涓棿浠跺皢瀵规潵鑷 INTERNAL_IPS 鎵璁剧疆鐨勫唴閮↖P鐨凥EAD璇锋眰鍙戦佸畾鍒剁殑 X-View HTTP澶淬侱jango鐨勮嚜鍔ㄦ枃妗g郴缁熶娇鐢ㄤ簡杩欎釜涓棿浠躲

Whats Next?

涓嬩竴绔

Web developers and database-schema designers dont always have the luxury of starting from scratch. In the next chapter, well cover how to integrate with legacy systems, such as database schemas youve inherited from the 1980s.

Web寮鍙戣呭拰鏁版嵁搴撴ā寮忚璁′汉鍛樺苟涓嶆绘槸浜湁鐧芥墜璧峰鎵撻犻」鐩殑濂緢鏈轰細銆備笅涓绔犲皢闃愯堪濡備綍闆嗘垚閬楃暀绯荤粺锛屾瘮濡傜户鎵胯嚜1980骞翠唬鐨勬暟鎹簱妯″紡銆

Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This work is licensed under the GNU Free Document License.
Hosting graciously provided by media temple
Chinese translate hosting by py3k.cn.