2010-05-26 19 views
29

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

उत्तर

32

आप decorator_from_middleware चाहते हैं।

from django.utils.decorators import decorator_from_middleware 

@decorator_from_middleware(MyMiddleware) 
def view_function(request): 
    #blah blah 

यह यूआरएल पर लागू नहीं होता है, लेकिन यह प्रति-दृश्य काम करता है, इसलिए आप इसके प्रभाव पर बढ़िया नियंत्रण कर सकते हैं।

+8

ठीक है, लेकिन क्या से एक दृश्य को छोड़ने के लिए अगर मैं मिडलवेयर को बाहर करने के बजाय उन्हें संलग्न चाहते आसान तरीका है। उदाहरण के लिए, मेरी सेटिंग्स फ़ाइल मिडलवेयर MIDDLEWARE_CLASSES = ('ए', 'बी', 'सी') सूचीबद्ध करती है और मैं चाहता हूं कि एक दृश्य ए और बी है लेकिन सी नहीं। क्या मिडलवेयर हटाने के लिए कोई सजावट है?केवल एक Django ऐप में इस कस्टम मिडलवेयर सामग्री की आवश्यकता है इसलिए मैं अपने आवेदन में हर दूसरे दृश्य में 'decorator_from_middleware' जोड़ना नहीं चाहता हूं। – hekevintran

+2

'@ csrf_exempt', जो आप जो पूछ रहे हैं उसके समान कुछ करता है, उस दृश्य पर ध्वज सेट करके काम करता है जिसे उसके बाद संबंधित सीएसआरएफ मिडलवेयर द्वारा चेक किया जाता है। सामान्य समाधान नहीं, ज़ाहिर है, लेकिन सिर्फ ध्यान देना। – sfridman

1

request.path के खिलाफ मिडलवेयर के लिए एक रैपर में यह देखने के लिए कि क्या दृश्य ऐप के भीतर है, और यदि प्रसंस्करण छोड़ें तो इसका उपयोग करें।

ए) इस एक कस्टम मिडलवेयर या एक है कि आप का विस्तार कर सकते है:

+0

तो मुझे अपने मिडलवेयर कोड में एक कथन का उपयोग करना होगा ताकि इसे कुछ ऐप्स में छोड़ दिया जा सके? – hekevintran

+0

रैपर में, मिडलवेयर स्वयं नहीं। –

+0

मिडलवेयर के लिए एक रैपर का उदाहरण क्या है? – hekevintran

5

यहाँ एक समाधान मैं हाल ही में उपयोग परिदृश्य आप नेड के जवाब के लिए एक टिप्पणी में प्रस्तुत संबोधित करने के लिए ...

यह मानता है कि है/अपनी खुद की मिडलवेयर वर्ग

बी) के साथ रैप क्योंकि process_view में आप view_func पैरामीटर निरीक्षण कर सकते हैं के बाद यह समाधान हो गया है अपने तर्क, process_request के बजाय process_view तक इंतजार कर सकते हैं। (या आप Ignacio द्वारा संकेत के अनुसार urlresolvers का उपयोग करने के लिए नीचे दिए गए कोड को समायोजित कर सकते हैं)।

# settings.py 
EXCLUDE_FROM_MY_MIDDLEWARE = set('myapp.views.view_to_exclude', 
    'myapp.views.another_view_to_exclude') 

# some_middleware.py 

from django.conf import settings 

def process_view(self, request, view_func, view_args, view_kwargs): 
    # Get the view name as a string 
    view_name = '.'.join((view_func.__module__, view_func.__name__)) 

    # If the view name is in our exclusion list, exit early 
    exclusion_set = getattr(settings, 'EXCLUDE_FROM_MY_MIDDLEWARE', set()) 
    if view_name in exclusion_set: 
     return None 

    # ... middleware as normal ... 
    # 
    # Here you can also set a flag of some sort on the `request` object 
    # if you need to conditionally handle `process_response` as well. 

इस पैटर्न को सामान्यीकृत करने का एक तरीका हो सकता है, लेकिन इसने मेरे लक्ष्य को काफी अच्छी तरह से पूरा किया।

अपने सामान्य प्रश्न का उत्तर देने के लिए, मुझे नहीं लगता कि Django पुस्तकालयों में कुछ भी है जो इस समय आपकी सहायता के लिए है। Django-users मेलिंग सूची के लिए एक अच्छा विषय होगा यदि इसे पहले ही संबोधित नहीं किया गया है।

5

मेरे पास इस मुद्दे के लिए एक वास्तविक समाधान है। चेतावनी; यह एक हैक का एक छोटा सा है।

""" Allows short-curcuiting of ALL remaining middleware by attaching the 
@shortcircuitmiddleware decorator as the TOP LEVEL decorator of a view. 

Example settings.py: 

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', 

    # THIS MIDDLEWARE 
    'myapp.middleware.shortcircuit.ShortCircuitMiddleware', 

    # SOME OTHER MIDDLE WARE YOU WANT TO SKIP SOMETIMES 
    'myapp.middleware.package.MostOfTheTimeMiddleware', 

    # MORE MIDDLEWARE YOU WANT TO SKIP SOMETIMES HERE 
) 

Example view to exclude from MostOfTheTimeMiddleware (and any subsequent): 

@shortcircuitmiddleware 
def myview(request): 
    ... 

""" 

def shortcircuitmiddleware(f): 
    """ view decorator, the sole purpose to is 'rename' the function 
    '_shortcircuitmiddleware' """ 
    def _shortcircuitmiddleware(*args, **kwargs): 
     return f(*args, **kwargs) 
    return _shortcircuitmiddleware 

class ShortCircuitMiddleware(object): 
    """ Middleware; looks for a view function named '_shortcircuitmiddleware' 
    and short-circuits. Relies on the fact that if you return an HttpResponse 
    from a view, it will short-circuit other middleware, see: 
    https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-request 
    """ 
    def process_view(self, request, view_func, view_args, view_kwargs): 
     if view_func.func_name == "_shortcircuitmiddleware": 
      return view_func(request, *view_args, **view_kwargs) 
     return None 

संपादित करें: पिछले संस्करण को हटाकर दो बार दृश्य चलाया गया।

0

Django urlmiddleware केवल विशिष्ट यूआरएल के मैप किए गए विचारों के लिए मिडलवेयर लागू करने की अनुमति देता है।

+0

अच्छा ऐप, हालांकि, यह अभी भी वैश्विक मिडलवेयर जोड़ता है जो अनुरोधित यूआरएल को किसी कॉन्फ़िगर किए गए यूआरएल विशिष्ट मिडलवेयर को फिर से जांचता है: https://github.com/d0ugal/django-urlmiddleware/blob/master/urlmiddleware/middleware.py#L18 – rednaw

1

सबसे अच्छी चीज जो मैं खोजने में सक्षम हूं, अनुरोध है कि अनुरोध वापस लौटकर मिडलवेयर पर छोड़ने के लिए request.path_info.startswith ('...') का उपयोग कर रहा है। अब, आप केवल छोड़ने के लिए मिडलवेयर बना सकते हैं और उसके बाद इसका वारिस कर सकते हैं। शायद आप कुछ भी आसान कर सकते हैं और उस सूची को अपनी सेटिंग्स.py में सहेज सकते हैं और फिर उन सभी को छोड़ दें। अगर मैं किसी भी तरह से गलत हूं, तो मुझे बताएं।

1

आप process_view विधि का उपयोग कर सकते हैं, जिसे दृश्य func को कॉल करने से पहले कहा जाता है। प्रक्रिया_दृश्य में आप जांच सकते हैं - यदि इस दृश्य को इस मिडलवेयर अवरोध की आवश्यकता है।

0

मुझे लगता है कि इस मिडलवेयर

from django.core.urlresolvers import resolve 
current_url = resolve(request.path_info).url_name 

if want to exclude url A, 

class your_middleware: 
    def process_request(request): 
     if not current_url == 'A': 
      "here add your code" 
संबंधित मुद्दे