2025, Oct 22 11:16

Wagtail i18n में 404 रीडायरेक्ट और रूट URL बग: DEBUG=False पर फिक्स

Wagtail i18n में रूट URL पर 404/रीडायरेक्ट क्यों टूटते हैं? Django में DEBUG=False पर 404.html टेम्पलेट से जुड़ी समस्या का कारण, प्रभाव और सुरक्षित समाधान।

डेवलपमेंट में Wagtail i18n अक्सर बिल्कुल स्थिर लगता है, लेकिन प्रोडक्शन में अचानक मुश्किल खड़ी कर सकता है। एक आम स्थिति: DEBUG = True होने पर द्विभाषी साइट रूट URL को अपने-आप सही लोकेल प्रीफिक्स, जैसे /en/ या /fr/, पर रीडायरेक्ट कर देती है। जैसे ही DEBUG = False करते हैं और https://example.com को बिना प्रीफिक्स के खोलते हैं, Resolver404 के साथ सर्वर एरर मिल जाता है। हाथ से /en/ जोड़ें तो सब चलता है; यहां तक कि /admin पर बिना ट्रेलिंग स्लैश के जाना भी फेल होता है, जबकि /admin/ ठीक खुलता है।

न्यूनतम सेटअप जो इस व्यवहार को दोहराता है

प्रोजेक्ट में मानक मिडलवेयर और i18n सेटिंग्स हैं, साथ में Wagtail की i18n सुविधाएँ सक्षम हैं।

MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    "django.middleware.security.SecurityMiddleware",
    "wagtail.contrib.redirects.middleware.RedirectMiddleware",
]
USE_I18N = True
USE_L10N = True
WAGTAIL_I18N_ENABLED = True
USE_TZ = True
WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE = True

URL कॉन्फ़िगरेशन i18n_patterns पर आधारित है और सामान्य Wagtail रूटिंग का उपयोग करता है:

from django.urls import path, include
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
# नीचे दिए गए प्रतीक का नाम बदला गया है ताकि व्यवहार बदले बिना मंशा स्पष्ट रहे
from search import views as search_handlers
urlpatterns = [
    path("admin/", include(wagtailadmin_urls)),
    path("documents/", include(wagtaildocs_urls)),
    path("search/", search_handlers.lookup, name="search"),
] + i18n_patterns(
    path("search/", search_handlers.lookup, name="search"),
    path("", include(wagtail_urls)),
)

असल में क्या हो रहा है

इस सेटअप में रीडायरेक्ट तब ट्रिगर होते हैं जब Wagtail 404 रिस्पॉन्स पकड़ लेता है। यह तरीका, जैसे लोकेल प्रीफिक्स अपने-आप जोड़ना, जैसी चीज़ों के लिए अहम है। लेकिन 404 रिस्पॉन्स का सचमुच रेंडर होना जरूरी है। अगर आपका 404.html ऐसी बेस टेम्पलेट को एक्सटेंड करता है जो प्री-रीडायरेक्ट चरण में उपलब्ध न रहने वाले कॉन्टेक्स्ट वैरिएबल्स की उम्मीद करता है, तो 404 की रेंडरिंग फेल हो जाती है; न 404 बनता है, न रीडायरेक्ट चलता है। इस मामले में base.html page का उपयोग करता है, लेकिन रीडायरेक्ट स्टेप से पहले वह वैरिएबल परिभाषित नहीं होता। DEBUG = True होने पर Django की एरर पेजें समस्या छिपा देती हैं; DEBUG = False में वही टेम्पलेट एरर साफ 404 और रीडायरेक्ट के बजाय सर्वर एरर बनकर सामने आता है।

समाधान

ध्यान रखें कि 404.html बिना यह मानकर भी रेंडर हो सके कि page मौजूद है। जो भी हिस्से page ऑब्जेक्ट पर निर्भर हों, उन्हें कंडीशनल में रखें, ताकि रीडायरेक्ट कैप्चर के दौरान टेम्पलेट सुरक्षित रहे।

उदाहरण: पहले का 404.html

{% extends "base.html" %}
{% block content %}
  <h1>Not found</h1>
  <h2>{{ page.title }}</h2>  {# `page` परिभाषित न होने पर टूटता है #}
{% endblock %}

उदाहरण: बाद का 404.html

{% extends "base.html" %}
{% block content %}
  <h1>Not found</h1>
  {% if page %}
    <h2>{{ page.title }}</h2>
    {# `page` पर निर्भर अन्य कोई भी हिस्से #}
  {% endif %}
{% endblock %}

इस सुरक्षा के साथ 404 पेज साफ़-सुथरे तरीके से रेंडर होता है, Wagtail अपना रीडायरेक्ट हैंडलिंग पूरा कर पाता है, और रूट URL सही लोकलाइज़्ड होम, जैसे /en/, पर पहुँचता है।

यह क्यों मायने रखता है

बहुभाषी Wagtail साइटों में शुरुआती लोकेल रिज़ॉल्यूशन अक्सर 404 कैप्चर और रीडायरेक्ट पर निर्भर होता है। यदि आपकी एरर टेम्पलेट उस फ्लो के दौरान इस्तेमाल न्यूनतम कॉन्टेक्स्ट में रेंडर नहीं हो पाती, तो आप प्रोडक्शन में रीडायरेक्ट का रास्ता ही बंद कर देते हैं। नतीजा: DEBUG = True और DEBUG = False के बीच समझाना मुश्किल अंतर, रूट URL विज़िट्स का टूटना, और ऐसी अजीब बातें कि /admin ट्रेलिंग स्लैश के बिना फेल हो, जबकि /admin/ चलता रहे।

निष्कर्ष

404.html को मजबूत रखें। Wagtail के रीडायरेक्ट लॉजिक के पूरा होने से पहले page या अन्य कॉन्टेक्स्ट वैरिएबल्स मौजूद मानकर न चलें। page पर निर्भर हिस्सों को {% if page %} ब्लॉक्स में रखें या उन्हें सशर्त बनाएं। जब 404 पेज उस कॉन्टेक्स्ट के बिना भी रेंडर हो सके, तो रीडायरेक्ट चेन अपेक्षित रूप से चलती है और आपका द्विभाषी रूटिंग डेवलपमेंट और प्रोडक्शन में एक जैसा व्यवहार करती है।

यह लेख StackOverflow के एक प्रश्न (लेखक: epok) और epok के उत्तर पर आधारित है।