Meán-earraíLink to this heading

Is creat crúcaí é Middleware i bpróiseáil iarrata/freagartha Django. Is córas “breiseán” éadrom, ar leibhéal íseal é chun ionchur nó aschur Django a athrú go domhanda.

Tá gach comhpháirt middleware freagrach as feidhm ar leith a dhéanamh. Mar shampla, cuimsíonn Django comhpháirt middleware, :class: ~django.contrib.auth.middleware.AuthenticationMiddleware, a chomhcheanglaíonn úsáideoirí le hiarratais ag baint úsáide as seisiúin.

Míníonn an doiciméad seo conas a oibríonn middleware, conas a ghníomhachaíonn tú middleware, agus conas do mheánware féin a scríobh. Loingíonn Django le roinnt earraí lárnacha ionsuite is féidir leat a úsáid díreach as an mbosca. Tá siad doiciméadaithe san: doc: `tagairt middleware ionsuite '</ref/middleware>.

Do mheán-earraí féin a scríobhLink to this heading

Is é monarcha earraí meánghlaoithe a thógann glaoch get_response agus a thugann middleware ar ais. Is féidir glaoch é middleware a ghlacann iarratas agus a thugann freagra ar ais, díreach cosúil le radharc.

Is féidir middleware a scríobh mar fheidhm a bhfuil cuma seo air:

Code
def simple_middleware(get_response):
    # One-time configuration and initialization.

    def middleware(request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    return middleware

Nó is féidir é a scríobh mar rang a bhfuil a gcásanna inghlaonta, mar seo:

Code
class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

D'fhéadfadh gurb é an glaoch get_response a sholáthraíonn Django an dearcadh iarbhír (más é seo an middleware liostaithe deireanach) nó d'fhéadfadh gurb é an chéad lár-earraí eile sa slabhra é. Ní gá don mheán-earraí reatha a bheith ar an eolas nó aire a thabhairt cad é go díreach é, ach go léiríonn sé cibé rud a thagann ina dhiaidh sin.

<template-response-middleware><exception-middleware>Is simplíocht bheag é an méid thuas - ní é an get_response` a ghlaoch don mheán deireanach sa slabhra an dearcadh iarbhír ach modh fillte ón láimhseálaí a thugann aire d'iarrat:ref: view middleware `, ag glaoch an dearcadh le hargóintí URL cuí, agus iarrth:ref: `teimplé-response agus:ref: `eisceacht <view-middleware>`middleware.

Ní féidir le Middleware tacú le Python sioncronach amháin (an réamhshocraithe), ach Python asincrónach, nó an dá cheann. Féach: ref: async-middleware le haghaidh sonraí faoin méid a thacaíonn tú a fhógairt, agus a fhios agat cén cineál iarratais atá á fháil agat.

Is féidir le middleware maireachtáil áit ar bith ar do chonair Python.

``__init__ (faigh_response) ``Link to this heading

Caithfidh monarchana middleware glacadh le hargóint get_response. Is féidir leat stát dhomhanda éigin a thionscnamh don middleware freisin. Coinnigh i gcuimhne cúpla rabhadh:

  • Cuireann Django tús le do middleware gan ach an argóint get_response, mar sin ní féidir leat ``__init__ () ``a shainiú mar a theastaíonn aon argóintí eile.

  • Murab ionann agus an modh __call__ () ``ar a dtugtar uair amháin in aghaidh an iarratais, thugtar ``__init__ () ach uaire, nuair a thosaíonn an freastalaí gréasáin.

Meán-earraí a mharcáil mar neamhúsáLink to this heading

Uaireanta bíonn sé úsáideach a chinneadh ag am tosaithe an gcaithfear píosa meán-earraí a úsáid. Sna cásanna seo, féadfaidh modh __init__ () ``do middleware a ardó:exc: `~django.core.exceptions.middlewareNotUsed`. Ansin bainfidh Django an middleware sin ón bpróiseas middleware agus logálfaidh teachtaireacht dífhabhtaithe chuig an logger: ref: `django-request-logger` nuai:setting: `DEBUG` ``True.

Middleware a ghníomhachtúLink to this heading

Chun comhpháirt middleware a ghníomhachtú, cuir é leis an liosta:setting: MIDDLEWARE i do shocruithe Django.

In: SETTING: MIDDLEWARE, léiríonn teaghrán gach comhpháirt middleware: an cosán iomlán Python chuig ainm ranga nó feidhm an mhonarcha middleware. <startproject>Mar shampla, seo an luach réamhshocraithe a chruthaí:djadmin: `django-admin startproject `:

Code
MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

Ní theastaíonn aon middleware ó shuiteáil Django -: setting: Is féidir le MIDDLEWARE a bheith folamh, más mian leat - ach moltar go láidir go n-úsáideann tú: class: ~django.middleware.common.commonMiddleware ar a laghad.

Tá tábhacht ag an ordú in:setting: MIDDLEWARE toisc gur féidir le middleware a bheith ag brath ar mheán-earraí eile. Mar shampla, stóráilíonn :class: ~django.contrib.auth.middleware.AuthenticationMiddleWare an t-úsáideoir fíordheimhnithe sa seisiún; dá bhrí sin, ní mór dó rith tar éis: :class: ~django.contrib.sessions.middleware.sessionMiddleware. Féach: ref: middleware-ording le haghaidh roinnt leideanna coitianta maidir le ranganna meán-earraí Django a ordú.

Ordú agus sraitheadh lár-earraíLink to this heading

Le linn na céime iarratais, sula nglaonn sé ar an radharc, cuireann Django middleware i bhfeidhm san ord a shainmhínítear é in:setting: MIDDLEWARE, barr anuas.

Is féidir leat smaoineamh air mar oinniún: is “ciseal” é gach rang middleware a fhilleann an radharc, atá i gcroílár an oinniúin. Má théann an t-iarratas trí na sraitheanna uile den oinniún (glaonn gach ceann ar get_response chun an t-iarratas a chur isteach chuig an gcéad chiseal eile), an bealach ar fad go dtí an radharc ag croílár, rachaidh an freagra ansin trí gach sraith (in ord droim) ar an mbealach ar ais amach.

Má chinneann ceann de na sraitheanna gearrchiorcad a dhéanamh agus freagra a thabhairt ar ais gan a get_response` a ghlaoch riamh, ní fheicfidh aon cheann de na sraitheanna den oinniún taobh istigh den chiseal sin (lena n-áirítear an radharc) an iarraidh ná an freagra. Ní thabharfaidh an freagra ar ais ach tríd na sraitheanna céanna a chuir an t-iarratas isteach tríd.

Crúcaí meán-earraí eileLink to this heading

Chomh maith leis an bpatrún lár-earraí iarrata/freagartha bunúsach a thuairiscítear níos luaithe, is féidir leat trí mhodh speisialta eile a chur le middleware rang-bhunaithe:

``próise_amharc () ``Link to this heading

process_view(request, view_func, view_args, view_kwargs)Link to this definition

Is é request ná: aicme: ~django.http.httpRequest réad. Is é view_func an fheidhm Python atá ar tí Django a úsáid. (Is é an réad feidhme iarbhír é, ní ainm na feidhme mar shreang.) Is liosta d'argóintí seasaimh é view_args a chuirfear ar aghaidh chuig an dearcadh, agus is foclóir argóintí eochairfhocal é view_kwargs a chuirfear chuig an dearcadh. Ní chuimsíonn view_args ná view_kwargs` an argóint chéad amharc (request).

Tugtar ar ``process_view () ``díreach sula nglaonn Django ar an radharc.

Ba chóir dó réad None nó an:class: ~django.http.httpResponse a thabhairt ar ais. Má fhilleann sé None ``, leanfaidh Django ar aghaidh ag próiseáil an iarratais seo, ag forghníomhú aon mheánware ``process_view () eile agus, ansin, an dearcadh cuí. Má fhilleann sé ruda:class: ~django.http.httpResponse réad, ní chuirfidh Django isteach ar an radharc cuí a ghlaoch; cuirfidh sé middleware freagartha i bhfeidhm ar ain:class: ~django.http.httpResponse agus cuirfidh sé an toradh ar ais.

``próise_eisceacht () ``Link to this heading

process_exception(request, exception)Link to this definition

Is é request ná: aicme: ~django.http.httpRequest réad. Is réad ````Eisceacht' é ``eisceacht' a ardaíonn an fheidhm amharc.

Glaonn Django ar process_exception () ``nuair a ardaíonn dearcadh eisceacht. Ba chóir go bhfaighidh ``process_exception () ``réad ``None nó ruda:class: ~django.http.httpResponse a thabhairt ar ais. Má fhilleann sé ruda:class: ~django.http.httpResponse réad, cuirfear an freagra teimpléid agus an lámhleabhair freagartha i bhfeidhm agus cuirfear an freagra mar thoradh air sin ar ais chuig an mbrabhsálaí. Seachas sin, tosaíonn :ref: `láimhseáil eisceachta réamhshocrai <error-views>the `isteach.

Arís, reáchtáiltear middleware in ord droim le linn na céime freagartha, lena n-áirítear ``process_exception`. Má thugann meán-earraí eisceachta freagra ar ais, ní ghlaofar ar chor ar chor ar bith ar na modhanna process_exception de na ranganna middleware thuas an middleware sin.

``próise_teimpléad_fhreagra () ``Link to this heading

process_template_response(request, response)Link to this definition

Is é request ná: aicme: ~django.http.httpRequest réad. Is é freagra ``an réad: :class: `~django.template.response.templateResponse réad (nó coibhéis) a chuirtear ar ais ag radharc Django nó ag middleware.

Tugtar process_template_response () ``díreach tar éis don amharc a bheith críochnaithe a chur i bhfeidhm, modh `render () ag an gcás freagartha, ag léiriú gurb é a:class: ~django.template.response.templateResponse nó coibhéiseach.

Caithfidh sé réad freagartha a thabhairt ar ais a chuireann modh render` i bhfeidhm. D'fhéadfadh sé an freagra a athrú trí response.template_name` agus response.context_data` a athrú, nó d'fhéadfadh sé branda nua:class: ~django.template.response.templateResponse nó coibhéis a chruthú agus a thabhairt ar ais.

Ní gá duit freagraí a thabhairt go sainráite - déanfar freagraí a thabhairt go huathoibríoch nuair a bheidh meán-earraí freagartha teimpléid uile glaoch.

Reáchtáiltear middleware in ord droim le linn na céime freagartha, lena n-áirítear ``process_template_response () ``.

Déileáil le freagraí sruthúLink to this heading

Unlike:class: ~django.http.httpResponse, :class: ~django.http.níl tréith ``content` ag ~django.http.StreamInghttPresponse. Mar thoradh air sin, ní féidir le middleware glacadh leis a thuilleadh go mbeidh tréith ``ábhar ``ag gach freagra. Má theastaíonn rochtain uathu ar an ábhar, ní mór dóibh freagraí sruthú a thástáil agus a n-iompar a choigeartú dá réir:

Code
if response.streaming:
    response.streaming_content = wrap_streaming_content(response.streaming_content)
else:
    response.content = alter_content(response.content)

StreamingHttpResponse allows both synchronous and asynchronous iterators. The wrapping function must match. Check StreamingHttpResponse.is_async if your middleware needs to support both types of iterator.

Láimhseáil eisceLink to this heading

Athraíonn Django eisceachtaí arna ardú ag an radharc nó ag middleware go huathoibríoch ina fhreagairt HTTP cuí le cód stádais earráide. :ref: Déantar `eisceachtaí áirithe <error-views>`a thiontú go cóid stádais 4xx, agus déantar eisceacht anaithnid a thiontú go cód stádais 500.

Tarlaíonn an tiontú seo roimh agus tar éis gach middleware (is féidir leat smaoineamh air mar an scannán tanaí idir gach sraith den oinniún), ionas gur féidir le gach middleware brath i gcónaí ar chineál éigin freagra HTTP a fháil ar ais ó a get_response` glaoch inghlaonta. Ní gá go mbeadh buartha a bheith buartha faoi a nglao chuig get_response` a fhilleadh i triacht/except` agus eisceacht a d'fhéadfadh a bheith ardaithe ag middleware nó an dearcadh níos déanaí a láimhseáil. Fiú má ardaíonn an chéad earraí eile sa slabhra eisceacht: Class: ~django.http.http404, mar shampla, ní fheicfidh do mheán-earraí an eisceacht sin; ina ionad sin gheobhaidh sé réad: ~django.http.http.httpResponse le a:attr: ~django.http.http.http.code de 404.

Is féidir leat socrú:setting: DEBUG_PROPAGATE_EXCEPTIONS go True chun an tiontú seo a scipeáil agus eisceachtaí a iomadú aníos.

Tacaíocht asincrónachLink to this heading

Is féidir le Middleware tacú le haon teaglaim d'iarratais sioncrónach agus asincrónach. Cuirfidh Django iarratais in oiriúint chun freastal ar riachtanais an middleware mura féidir leis tacú leis an dá cheann, ach ag pionós feidhmíochta.

De réir réamhshocraithe, glacann Django leis nach bhfuil do middleware in ann ach iarratais sioncrónacha a láimhseáil. Chun na toimhdeanna seo a athrú, socraigh na tréithe seo a leanas ar do fheidhm nó rang monarchan middleware:

  • Is boolean é sync_capable a thugann le fios an féidir leis an meán-earraí iarratais sioncrónach a láimhseáil. Réamhshocraithe go True.

  • Is boolean é async_capable` a thugann le fios an féidir leis an meán-earraí iarratais asincrónacha a láimhseáil. Réamhshocraithe go False.

If your middleware has both sync_capable = True and async_capable = True, then Django will pass it the request without converting it. In this case, you can work out if your middleware will receive async requests by checking if the get_response object you are passed is a coroutine function, using inspect.iscoroutinefunction.

Tá an modúl ``django.utils.decorators ``: func: ~django.utils.decorators.sync_only_middleware, :func: ~django.utils.decorators.async_only_middleware, agus:func: `~django.utils.decorators.sync_and_async_middleware' `maisitheoirí a ligeann duit na bratacha seo a chur i bhfeidhm ar fheidhmeanna monarchan meánearraí.

Caithfidh an t-inghlaoch a fhilleadh a mheaitseáil le nádúr sioncrónaithe nó async an mhodha get_response. Má tá get_response` asincrónach agat, ní mór duit feidhm coroutine a thabhairt ar ais (async def).

Ba chóir modhanna process_view, process_template_response` agus process_exception, má chuirtear ar fáil iad, a oiriúnú freisin chun an modh sionc/async a mheaitseáil. Mar sin féin, déanfaidh Django iad a oiriúnú ina n-aonar de réir mar is gá mura ndéanann tú, ag pionós feidhmíochta breise.

Seo sampla de conas feidhm middleware a chruthú a thacaíonn leis an dá cheann:

Code
from inspect import iscoroutinefunction
from django.utils.decorators import sync_and_async_middleware


@sync_and_async_middleware
def simple_middleware(get_response):
    # One-time configuration and initialization goes here.
    if iscoroutinefunction(get_response):

        async def middleware(request):
            # Do something here!
            response = await get_response(request)
            return response

    else:

        def middleware(request):
            # Do something here!
            response = get_response(request)
            return response

    return middleware

Agus meán-earraí aicme asincrónach á úsáid agat, ní mór duit a chinntiú go ndéantar cásanna a mharcáil i gceart mar fheidhmeanna coroutine:

Code
from inspect import iscoroutinefunction, markcoroutinefunction


class AsyncMiddleware:
    async_capable = True
    sync_capable = False

    def __init__(self, get_response):
        self.get_response = get_response
        if iscoroutinefunction(self.get_response):
            markcoroutinefunction(self)

    async def __call__(self, request):
        response = await self.get_response(request)
        # Some logic ...
        return response

Meán-earraí i stíl réamh-Django 1.10 a uasghrádúLink to this heading

class django.utils.deprecation.MiddlewareMixinLink to this definition

Soláthraíonn Django Django.Utils.DEPRECATION.MIDDLEWAREMIXIN chun ranganna middleware a chruthú atá comhoiriúnach leis an mbeach:setting: MIDDLEWARE agus an sean-``MIDDLEWARE_CLASSES` a éascú, agus tacú le hiarratais sioncrónach agus asincrónach. Tá gach rang middleware atá san áireamh le Django comhoiriúnach leis an dá shocrú.

Soláthraíonn an mixin modh __init__ () ``a éilíonn argóint ``get_response agus a stóráilíonn sé i self.get_response.

An modh ``__call__ () ``:

  1. Glaonna ```self.process_request (request) ``(má shainmhínítear).

  2. Glaonna ar ``self.get_response (request) ``chun an freagra a fháil ó mheán-earraí níos déanaí agus an radharc.

  3. Glaonna ```self.process_response (iarratas, freagra) ``(má shainmhínítear).

  4. Tugann an freagra ar ais.

Má úsáidtear é le MIDDLEWARE_CLASSES`, ní úsáidfear an modh __call__ () ``riamh; glaonn Django ``process_request () agus ``process_response () ``go díreach.

I bhformhór na gcásanna, is leor oidhreacht ón meascán seo chun meán-earraí sean-stíl a dhéanamh comhoiriúnach leis an gcóras nua le comhoiriúnacht leordhóthanach cúl. Beidh an séimeantaic gearrchiorcaid nua neamhdhíobhálach nó fiú tairbheach don mheán-earraí atá ann cheana. I gcúpla cás, b'fhéidir go mbeadh roinnt athruithe ag teastáil ó rang middleware chun dul in oiriúint don shéimeantaic nua.

Seo iad na difríochtaí iompraíochta idir úsáid: setting: MIDDLEWARE agus MIDDLEWARE_CLASSES`:

  1. Faoi MIDDLEWARE_CLASSES, beidh a mhodh process_response` ag gach middleware i gcónaí, fiú má ghearrchiorcáladh meán-earraí níos luaithe trí fhreagra a thabhairt ar ais óna mhodh process_request. Faoi: Socrú: MIDDLEWARE, iompraíonn middleware níos cosúil le oinniún: is iad na sraitheanna a théann freagra tríd ar an mbealach amach na sraitheanna céanna a chonaic an t-iarratas ar an mbealach isteach. Má tá gearrchiorcaid lár-earraí ann, ní fheicfidh an freagra ach an middleware sin agus na cinn roimh i:setting: MIDDLEWARE.

  2. Faoi MIDDLEWARE_CLASSES, cuirtear process_exception` i bhfeidhm ar eisceachtaí a ardaítear ó mhodh process_request` middleware. Fao:SETTING: MIDDLEWARE, ní bhaineann process_exception ach le heisceachtaí a ardaíodh ón radharc (nó ón modh render de a:class: ~django.template.response.templateResponse). Déantar eisceachtaí a ardaítear ó mheán-earraí a thiontú go dtí an freagra HTTP cuí agus ansin cuirtear ar aghaidh chuig an chéad mheán-earraí eile.

  3. Faoi MIDDLEWARE_CLASSES`, má ardaíonn modh process_response eisceacht, scipeántar modhanna process_response gach middleware roimhe seo agus cuirtear freagra HTTP 500 Inmheánach Freastala ar ais i gcónaí (fiú má bhí an eisceacht m.sh:class: ~django.http.http404). Fao:SETTING: MIDDLEWARE, tionófar eisceacht a ardaíodh ó mheán-earraí láithreach go dtí an freagra HTTP cuí, agus ansin feicfidh an chéad mheán-earraí eile atá i líne an freagra sin. Ní scipeántar Middleware riamh mar gheall ar mheán-earraí a ardaíonn eisceacht.