खोज…


परिचय

Django में Middleware एक फ्रेमवर्क है जो कोड को प्रतिक्रिया / अनुरोध प्रसंस्करण में हुक करने और Django के इनपुट या आउटपुट को बदलने की अनुमति देता है।

टिप्पणियों

इससे पहले कि यह निष्पादन में शामिल हो, मिडलवेयर को अपनी सेटिंग में शामिल होना MIDDLEWARE_CLASSES सूची। एक नई परियोजना बनाते समय Django द्वारा प्रदान की गई डिफ़ॉल्ट सूची निम्नानुसार है:

MIDDLEWARE_CLASSES = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

इन सभी कार्यों है कि हर अनुरोध पर क्रम में चलेंगे (एक बार से पहले ही में आपके विचार कोड तक पहुँच जाता है views.py के लिए उलटे क्रम में और एक बार process_response संस्करण 1.10 से पहले कॉलबैक,)। वे कई तरह की चीजें करते हैं जैसे कि क्रॉस साइट रिक्वेस्ट फॉरेरी (सीएसआरएफ) टोकन इंजेक्ट करना

आदेश मायने रखता है क्योंकि अगर कोई मिडलवेयर रीडायरेक्ट करता है, तो उसके बाद के सभी मिडलवेयर कभी नहीं चलेंगे। या अगर कोई मिडिलवेयर सीएसआरएफ टोकन की उम्मीद करता है, तो उसे CsrfViewMiddleware बाद CsrfViewMiddleware

अनुरोध में डेटा जोड़ें

Django दृश्य के भीतर उपयोग के लिए अनुरोधों पर अतिरिक्त डेटा जोड़ना वास्तव में आसान बनाता है। उदाहरण के लिए, हम अनुरोध के मेटा पर उपडोमेन को पार्स कर सकते हैं और इसे मिडलवेयर का उपयोग करके अनुरोध पर एक अलग संपत्ति के रूप में संलग्न कर सकते हैं।

class SubdomainMiddleware:
    def process_request(self, request):
        """
        Parse out the subdomain from the request
        """
        host = request.META.get('HTTP_HOST', '')
        host_s = host.replace('www.', '').split('.')
        request.subdomain = None
        if len(host_s) > 2:
            request.subdomain = host_s[0]

यदि आप अपने अनुरोध में मिडलवेयर के साथ डेटा जोड़ते हैं, तो आप उस नए जोड़े गए डेटा को लाइन के नीचे एक्सेस कर सकते हैं। यहाँ हम पार्स किए गए उपडोमेन का उपयोग इस बात का निर्धारण करने के लिए करेंगे कि आपके एप्लिकेशन को कौन सा संगठन एक्सेस कर रहा है। यह दृष्टिकोण उन ऐप्स के लिए उपयोगी है, जिन्हें वाइल्डकार्ड सबडोमेन के साथ DNS सेटअप के साथ तैनात किया जाता है, जो सभी एक ही उदाहरण को इंगित करते हैं और ऐप को एक्सेस करने वाला व्यक्ति एक स्किन वाले संस्करण को एक्सेस प्वाइंट पर निर्भर करना चाहता है।

class OrganizationMiddleware:
    def process_request(self, request):
        """
        Determine the organization based on the subdomain
        """
        try:
            request.org = Organization.objects.get(domain=request.subdomain)
        except Organization.DoesNotExist:
            request.org = None

याद रखें कि जब मिडलवेयर एक-दूसरे पर निर्भर होते हैं तो ऑर्डर ऑर्डर होता है। अनुरोधों के लिए, आप चाहते हैं कि निर्भरता के बाद आश्रित मिडलवेयर को रखा जाए।

MIDDLEWARE_CLASSES = [
    ...
    'myapp.middleware.SubdomainMiddleware',
    'myapp.middleware.OrganizationMiddleware',
    ...
]

आईपी पते द्वारा फ़िल्टर करने के लिए मिडिलवेयर

पहला: पथ संरचना

यदि आपके पास यह नहीं है, तो आपको संरचना के बाद अपने ऐप के भीतर मिडलवेयर फ़ोल्डर बनाने की आवश्यकता है:

yourproject/yourapp/middleware

फ़ोल्डर मिडलवेयर को सेटिंगहोल्ड, यूआरएल, टेम्प्लेट के समान फ़ोल्डर में रखा जाना चाहिए ...

महत्वपूर्ण: मिडलवेयर फ़ोल्डर के अंदर init .py खाली फ़ाइल बनाना न भूलें ताकि आपका ऐप इस फ़ोल्डर को पहचान सके

आपके मिडलवेयर कक्षाओं वाले एक अलग फ़ोल्डर होने के बजाय, अपने कार्यों को एक फ़ाइल, yourproject/yourapp/middleware.py में रखना संभव है

दूसरा: मिडलवेयर बनाएं

अब हमें अपने कस्टम मिडलवेयर के लिए एक फाइल बनानी चाहिए। इस उदाहरण में मान लेते हैं कि हम एक ऐसा मिडलवेयर चाहते हैं जो उपयोगकर्ताओं को उनके आईपी पते के आधार पर फ़िल्टर करे, हम एक फाइल बनाते हैं, जिसका नाम filter_ip_middleware.py है :

#yourproject/yourapp/middleware/filter_ip_middleware.py
from django.core.exceptions import PermissionDenied    

class FilterIPMiddleware(object):
    # Check if client IP address is allowed
    def process_request(self, request):
        allowed_ips = ['192.168.1.1', '123.123.123.123', etc...] # Authorized ip's
        ip = request.META.get('REMOTE_ADDR') # Get client IP address
        if ip not in allowed_ips:
            raise PermissionDenied # If user is not allowed raise Error

       # If IP address is allowed we don't do anything
       return None

तीसरा: हमारी 'सेटिंग' में मिडलवेयर जोड़ें

हमें सेटिंग्स के अंदर 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',
     # Above are Django standard middlewares

     # Now we add here our custom middleware
     'yourapp.middleware.filter_ip_middleware.FilterIPMiddleware'
)

किया हुआ! अब हर ग्राहक का प्रत्येक अनुरोध आपके कस्टम मिडलवेयर को कॉल करेगा और आपके कस्टम कोड को प्रोसेस करेगा!

विश्व स्तर पर हैंडलिंग अपवाद

मान लीजिए कि आपने डेटाबेस में किसी ऑब्जेक्ट को संशोधित करने के प्रयासों का पता लगाने के लिए कुछ तर्क लागू किए हैं, जबकि परिवर्तन प्रस्तुत करने वाले क्लाइंट के पास नवीनतम संशोधन नहीं हैं। यदि ऐसा मामला होता है, तो आप एक कस्टम अपवाद ConfictError(detailed_message)

अब आप एक HTTP 409 (कॉन्फिक्ट) स्टेटस कोड वापस करना चाहते हैं जब यह त्रुटि होती है। आप आमतौर पर प्रत्येक दृश्य में इसे संभालने के बजाय मिडलवेयर के रूप में उपयोग कर सकते हैं जो इस अपवाद को बढ़ा सकता है।

class ConfictErrorHandlingMiddleware:
    def process_exception(self, request, exception):
        if not isinstance(exception, ConflictError):
            return  # Propagate other exceptions, we only handle ConflictError
        context = dict(confict_details=str(exception))
        return TemplateResponse(request, '409.html', context, status=409)

Django 1.10 मिडलवेयर की नई शैली को समझना

Django 1.10 ने एक नई मिडलवेयर शैली शुरू की, जहां process_request और process_response को एक साथ process_response जाता है।

इस नई शैली में, एक मिडलवेयर एक कॉल करने योग्य है जो एक और कॉल करने योग्य रिटर्न देता है । खैर, वास्तव में पूर्व एक मिडलवेयर कारखाना है और बाद वाला वास्तविक मिडलवेयर है

मिडलवेयर फैक्ट्री एकल तर्क के रूप में अगले मिडलवेयर को मिडिलवेर्स स्टैक में ले जाती है, या स्टैक के निचले भाग तक पहुंचने पर खुद को देखती है।

मिडलवेयर अनुरोध को एकल तर्क के रूप में लेता है और हमेशा एक HttpResponse देता है

यह बताने के लिए कि नई शैली के मिडलवेयर कैसे काम करते हैं, इसका सबसे अच्छा उदाहरण संभवतः यह दिखाना है कि कैसे एक पिछड़े-संगत मिडलवेयर को बनाया जाए :

class MyMiddleware:

    def __init__(self, next_layer=None):
        """We allow next_layer to be None because old-style middlewares
        won't accept any argument.
        """
        self.get_response = next_layer

    def process_request(self, request):
        """Let's handle old-style request processing here, as usual."""
        # Do something with request
        # Probably return None
        # Or return an HttpResponse in some cases

    def process_response(self, request, response):
        """Let's handle old-style response processing here, as usual."""
        # Do something with response, possibly using request.
        return response

    def __call__(self, request):
        """Handle new-style middleware here."""
        response = self.process_request(request)
        if response is None:
            # If process_request returned None, we must call the next middleware or
            # the view. Note that here, we are sure that self.get_response is not
            # None because this method is executed only in new-style middlewares.
            response = self.get_response(request)
        response = self.process_response(request, response)
        return response


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow