django urls एक अनुगामी स्लैश के बिना पुनर्निर्देशित नहीं करता है


89

मुझे दो एप्लिकेशन दो अलग-अलग कंप्यूटरों पर स्थित हैं। कंप्यूटर ए पर, urls.pyफ़ाइल में मेरे पास निम्न की तरह एक पंक्ति है:

(r'^cast/$', 'mySite.simulate.views.cast')

और वह यूआरएल दोनों के लिए काम करेंगे mySite.com/cast/और mySite.com/cast। लेकिन कंप्यूटर पर बीआई में एक समान url लिखा होता है जैसे:

(r'^login/$', 'mySite.myUser.views.login')

कंप्यूटर B पर किसी कारण से url mySite.com/login/ a काम करेगा, लेकिन mySite.com/loginलटकाएगा और वापस mySite.com/login/कंप्यूटर पर यह पसंद नहीं करेगा। क्या ऐसा कुछ है जो मुझे याद नहीं है? दोनों url.pyफाइलें मुझे एक जैसी लगती हैं।

जवाबों:


103

APPEND_SLASHसेटिंग्स फ़ाइल में अपनी सेटिंग की जाँच करें

django डॉक्स में अधिक जानकारी


4
"सही पर सेट होने पर, यदि अनुरोध URL URLconf के किसी भी पैटर्न से मेल नहीं खाता है और यह स्लैश में समाप्त नहीं होता है, तो HTTP रीडायरेक्ट उसी URL को स्लैश किए गए के साथ जारी किया जाता है। ध्यान दें कि रीडायरेक्ट हो सकता है। खो जाने के लिए POST अनुरोध में प्रस्तुत कोई भी डेटा। " "यदि CommonMiddleware स्थापित किया गया है तो केवल APPEND_SLASH सेटिंग का उपयोग किया जाता है ..."। मैं एक क्लीनर समाधान के लिए माइकल गेंडिन के जवाब को पसंद करता हूं।
Wtower

3
यदि आप अपने urlpatterns के अंतिम प्रवेश पर अतिरिक्त "पकड़" सभी url का उपयोग कर रहे हैं तो यह काम नहीं करता है। @ स्पीडप्लेन का जवाब उन स्थितियों पर भी काम करेगा। लेकिन, निश्चित रूप से, यह सरल है और इसका उपयोग किया जाना चाहिए यदि कोई "कैच ऑल" यूरलपटन्ट एंट्रीज़ नहीं हैं।
np8

194

या आप अपने यूआरएल इस तरह लिख सकते हैं:

(r'^login/?$', 'mySite.myUser.views.login')

अनुगामी स्लैश के बाद प्रश्न चिन्ह इसे regexp में वैकल्पिक बनाता है। यदि आप कुछ कारणों से APPEND_SLASH सेटिंग का उपयोग नहीं करना चाहते हैं तो इसका उपयोग करें।


11
मुझे भोले कहो - लेकिन इस उत्तर को दस लाख अपवित्र और django faq में प्रवेश क्यों नहीं मिला?
फर्गल मोरन

42
सुनिश्चित करें कि आप एसईओ कारणों से ऐसा नहीं करना चाहते हैं - दो वैध URL की तुलना में एक कैनोनिकल URL पर पुनर्निर्देशित करना बेहतर है।
ब्रायन फ्रांटज़

47
यदि आप Django का उपयोग करके एक RESTful API creting कर रहे हैं, तो यह एक अच्छा समाधान हो सकता है जब डेवलपर्स URL को सीधे इंगित करने के लिए डेटा पोस्ट करते हैं। उपयोग करते समय APPEND_SLASH, यदि वे गलती से स्लैश के बिना इसे भेजते हैं, और आपका urlconf एक अनुगामी स्लैश के साथ है तो उन्हें POST अनुरोधों को पुनर्निर्देशित करने पर डेटा खोने के बारे में एक अपवाद मिलेगा।
ओरपो

5
इस समाधान के साथ समस्या यह है कि आप एक ही पेज को 2 यूआरएल के तहत (ट्रेलिंग के साथ और बिना /) - मैला, क्रॉलर्स के लिए खराब, बनाए रखने के लिए कठिन, एक नई प्रणाली की ओर पलायन करने के लिए कठिन है (क्योंकि यह बहुत आसान है)
जियारो

अच्छा उत्तर। मैं स्लैश को समाप्त करना पसंद करूंगा (क्योंकि यह किसी नई चीज़ की शुरुआत को दर्शाता है, न कि किसी चीज़ का अंत (जैसे / आदि), लेकिन यह मानक (/ देखने) और गैर-मानक (/ देखने /) के लिए अनुमति देता है।
डेविड बेट्ज़

19

यह @Michael Gendin के उत्तर में सुधार करता है। उसका उत्तर दो अलग URL के साथ समान पृष्ठ परोसता है। बेहतर होगा कि loginस्वचालित रूप से पुनर्निर्देशित किया जाए login/, और फिर मुख्य पृष्ठ के रूप में बाद की सेवा करें:

from django.conf.urls import patterns
from django.views.generic import RedirectView

urlpatterns = patterns('',
    # Redirect login to login/
    (r'^login$', RedirectView.as_view(url = '/login/')),
    # Handle the page with the slash.
    (r'^login/', "views.my_handler"),
)

बहुत उपयोगी है जब आपके पास अंत में एक कैच-ऑल URL होता है।
१०

रेगेक्स के साथ यह कैसे काम कर सकता है? यदि मूल यूआरएल उदाहरण के लिए क्लाइंट नाम के साथ एक रेगेक्स से मेल खाता है
निकोलो गैस्पारिनी

@ निकोलगसपरिनी - Django के नए संस्करणों में एक pattern_namearg है जिसका उपयोग redirectसभी url args के साथ किया जाता है जो कि मेल खाते हैं।
टिम टिस्डल


1

रीडायरेक्ट के बिना स्लैश को जोड़ें , सेटिंग्स में कॉमनमेडलवेयर के बजाय इसका उपयोग करें, Django 2.1:

MIDDLEWARE = [
    ...
    # 'django.middleware.common.CommonMiddleware',
    'htx.middleware.CommonMiddlewareAppendSlashWithoutRedirect',
    ...
]

अपने मुख्य ऐप निर्देशिका मिडिलवेयरमदो में जोड़ें :

from django.http import HttpResponsePermanentRedirect, HttpRequest
from django.core.handlers.base import BaseHandler
from django.middleware.common import CommonMiddleware
from django.conf import settings


class HttpSmartRedirectResponse(HttpResponsePermanentRedirect):
    pass


class CommonMiddlewareAppendSlashWithoutRedirect(CommonMiddleware):
    """ This class converts HttpSmartRedirectResponse to the common response
        of Django view, without redirect.
    """
    response_redirect_class = HttpSmartRedirectResponse

    def __init__(self, *args, **kwargs):
        # create django request resolver
        self.handler = BaseHandler()

        # prevent recursive includes
        old = settings.MIDDLEWARE
        name = self.__module__ + '.' + self.__class__.__name__
        settings.MIDDLEWARE = [i for i in settings.MIDDLEWARE if i != name]

        self.handler.load_middleware()

        settings.MIDDLEWARE = old
        super(CommonMiddlewareAppendSlashWithoutRedirect, self).__init__(*args, **kwargs)

    def process_response(self, request, response):
        response = super(CommonMiddlewareAppendSlashWithoutRedirect, self).process_response(request, response)

        if isinstance(response, HttpSmartRedirectResponse):
            if not request.path.endswith('/'):
                request.path = request.path + '/'
            # we don't need query string in path_info because it's in request.GET already
            request.path_info = request.path
            response = self.handler.get_response(request)

        return response

0

मुझे भी यही समस्या हुई है। मेरे मामले में यह urls.py में कुछ पुराने संस्करण से बासी बचे हुए थे, स्टैटिकफाइल्स से पहले:

url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL.lstrip('/'),
    'django.views.static.serve',
    kwargs={'document_root': settings.MEDIA_ROOT}),

MEDIA_URL खाली था, इसलिए यह पैटर्न सब कुछ से मेल खाता था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.