Django 2.1 - URL dispatcher

URL प्रेषणकर्ता




django

URL प्रेषणकर्ता

एक उच्च गुणवत्ता वाले वेब एप्लिकेशन में एक स्वच्छ, सुरुचिपूर्ण URL योजना एक महत्वपूर्ण विवरण है। Django आपको ऐसे URL डिज़ाइन करने देता है जो आप चाहते हैं, जिसमें कोई फ्रेमवर्क सीमाएँ नहीं हैं।

कोई .php या .cgi आवश्यक नहीं है, और निश्चित रूप से उस 0,2097,1-1-1928,00 बकवास में से कोई भी नहीं है।

वर्ल्ड वाइड वेब निर्माता टिम बर्नर्स-ली द्वारा कूल यूआरआई को नहीं बदला जाए , इस बात पर उत्कृष्ट तर्क के लिए कि URL क्यों साफ और प्रयोग करने योग्य होने चाहिए।

अवलोकन

किसी एप्लिकेशन के लिए URL डिज़ाइन करने के लिए, आप अनौपचारिक रूप से URLconf (URL कॉन्फ़िगरेशन) नामक पायथन मॉड्यूल बनाते हैं। यह मॉड्यूल शुद्ध पायथन कोड है और यह URL पथ अभिव्यक्तियों के बीच पायथन फ़ंक्शन (आपके विचार) के लिए मैपिंग है।

यह मानचित्रण आवश्यकतानुसार कम या ज्यादा हो सकता है। यह अन्य मैपिंग को संदर्भित कर सकता है। और, क्योंकि यह शुद्ध पायथन कोड है, इसका निर्माण गतिशील रूप से किया जा सकता है।

Django भी सक्रिय भाषा के अनुसार URL का अनुवाद करने का एक तरीका प्रदान करता है। अधिक जानकारी के लिए अंतर्राष्ट्रीयकरण दस्तावेज़ देखें।

कैसे Django एक अनुरोध संसाधित करता है

जब कोई उपयोगकर्ता आपके Django द्वारा संचालित साइट से एक पेज का अनुरोध करता है, तो यह वह एल्गोरिथ्म है जो सिस्टम यह निर्धारित करने के लिए करता है कि कौन सा पायथन कोड निष्पादित करने के लिए है:

  1. Django उपयोग करने के लिए रूट URLconf मॉड्यूल निर्धारित करता है। आमतौर पर, यह ROOT_URLCONF सेटिंग का मान है, लेकिन यदि आने वाली HttpRequest ऑब्जेक्ट में एक urlconf विशेषता (मिडलवेयर द्वारा सेट) है, तो इसका मान ROOT_URLCONF सेटिंग के स्थान पर उपयोग किया जाएगा।
  2. Django उस पायथन मॉड्यूल को लोड करता है और चर urlpatterns । यह django.urls.path() और / या django.urls.re_path() उदाहरणों की पायथन सूची होनी चाहिए।
  3. Django प्रत्येक URL पैटर्न के माध्यम से चलता है, क्रम में, और पहले URL पर रुकता है जो अनुरोधित URL से मेल खाता है।
  4. एक बार URL पैटर्न के मिलान के बाद, Django दिए गए दृश्य को आयात और कॉल करता है, जो कि एक साधारण पायथन फ़ंक्शन (या क्लास-आधारित दृश्य ) है। दृश्य निम्नलिखित तर्कों से गुजरता है:
    • HttpRequest का एक उदाहरण।
    • यदि मिलान किया गया URL पैटर्न बिना किसी नाम के समूहों को लौटाता है, तो नियमित अभिव्यक्ति से मिलान को स्थितिगत तर्क के रूप में प्रदान किया जाता है।
    • कीवर्ड तर्क पथ अभिव्यक्ति द्वारा मिलान किए गए किसी भी नामित भागों से बने होते हैं, जो वैकल्पिक kwargs तर्क में django.urls.path() या django.urls.re_path() में निर्दिष्ट किसी भी तर्क से django.urls.path()
  5. यदि कोई URL प्रतिमान मेल नहीं खाता है, या यदि इस प्रक्रिया में किसी बिंदु के दौरान अपवाद उठाया गया है, तो Django एक उपयुक्त त्रुटि-हैंडलिंग दृश्य को आमंत्रित करता है। नीचे देखें त्रुटि से निपटने

उदाहरण

यहाँ एक नमूना URLconf है:

from django.urls import path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]

टिप्पणियाँ:

  • URL से मान कैप्चर करने के लिए, कोण कोष्ठक का उपयोग करें।
  • कैप्चर किए गए मान वैकल्पिक रूप से एक कनवर्टर प्रकार शामिल कर सकते हैं। उदाहरण के लिए, पूर्णांक पैरामीटर कैप्चर करने के लिए <int:name> का उपयोग करें। यदि कोई कन्वर्टर शामिल नहीं है, तो किसी भी स्ट्रिंग, / वर्ण को छोड़कर, मिलान किया जाता है।
  • कोई प्रमुख स्लैश जोड़ने की आवश्यकता नहीं है, क्योंकि प्रत्येक URL में ऐसा है। उदाहरण के लिए, यह articles , /articles नहीं।

उदाहरण अनुरोध:

  • /articles/2005/03/ लिए एक अनुरोध सूची में तीसरी प्रविष्टि से मेल खाता है। Django फ़ंक्शन views.month_archive(request, year=2005, month=3) को कॉल करेगा।
  • /articles/2003/ सूची में पहले पैटर्न से मेल खाएंगे, न कि दूसरे से, क्योंकि पैटर्न का परीक्षण क्रम में किया जाता है, और पहला पास करने वाला पहला टेस्ट होता है। इस तरह के विशेष मामलों को सम्मिलित करने के लिए आदेश का शोषण करने के लिए स्वतंत्र महसूस करें। यहाँ, Django फ़ंक्शन views.special_case_2003(request) को कॉल करेगा
  • /articles/2003 इनमें से किसी भी पैटर्न से मेल नहीं खाता, क्योंकि प्रत्येक पैटर्न के लिए आवश्यक है कि URL स्लैश के साथ समाप्त हो।
  • /articles/2003/03/building-a-django-site/ अंतिम पैटर्न से मेल खाते हैं। Django फ़ंक्शन views.article_detail(request, year=2003, month=3, slug="building-a-django-site") को कॉल करेगा।

पथ बदलने वाले

निम्नलिखित पथ कन्वर्टर्स डिफ़ॉल्ट रूप से उपलब्ध हैं:

  • str - पथ विभाजक, '/' को छोड़कर, किसी भी गैर-रिक्त स्ट्रिंग से मेल खाता है। यदि कोई कनवर्टर अभिव्यक्ति में शामिल नहीं है तो यह डिफ़ॉल्ट है।
  • int - शून्य या किसी धनात्मक पूर्णांक से मेल खाता है। एक int लौटाता है।
  • slug - किसी भी स्लग स्ट्रिंग से मेल खाता है जिसमें ASCII अक्षर या संख्याएँ, साथ ही हाइफ़न और अंडरस्कोर वर्ण शामिल हैं। उदाहरण के लिए, building-your-1st-django-site
  • uuid - एक स्वरूपित UUID से मेल खाता है। एक ही पृष्ठ पर कई URL को मैप करने से रोकने के लिए, डैश को शामिल किया जाना चाहिए और अक्षरों को कम किया जाना चाहिए। उदाहरण के लिए, 075194d3-6885-417e-a8a8-6c931e272f00 । एक UUID उदाहरण देता है।
  • path - पथ विभाजक, '/' सहित किसी भी गैर-रिक्त स्ट्रिंग से मेल खाता है। यह आपको एक URL पथ के एक खंड के बजाय एक पूर्ण URL पथ के विरुद्ध मिलान करने की अनुमति देता है।

कस्टम पथ कन्वर्टर्स को पंजीकृत करना

अधिक जटिल मिलान आवश्यकताओं के लिए, आप अपने स्वयं के पथ कन्वर्टर्स को परिभाषित कर सकते हैं।

एक कनवर्टर एक वर्ग है जिसमें निम्नलिखित शामिल हैं:

  • एक स्ट्रिंग के रूप में एक regex वर्ग विशेषता।
  • A to_python(self, value) विधि, जो मिलान किए गए स्ट्रिंग को उस प्रकार में परिवर्तित करने का काम करती है जिसे व्यू फंक्शन में पास किया जाना चाहिए। यदि यह दिए गए मान को परिवर्तित नहीं कर सकता है तो इसे ValueError को उठाना चाहिए।
  • A to_url(self, value) विधि, जो URL में उपयोग किए जाने वाले पायथन प्रकार को एक स्ट्रिंग में परिवर्तित करने का काम करती है।

उदाहरण के लिए:

class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%04d' % value

अपने URLconf में register_converter() का उपयोग करके कस्टम कन्वर्टर कक्षाएं register_converter() :

from django.urls import path, register_converter

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<yyyy:year>/', views.year_archive),
    ...
]

नियमित अभिव्यक्ति का उपयोग करना

यदि आपके URL पैटर्न को परिभाषित करने के लिए पथ और कन्वर्टर्स सिंटैक्स पर्याप्त नहीं है, तो आप नियमित अभिव्यक्तियों का भी उपयोग कर सकते हैं। ऐसा करने के लिए, django.urls.path() बजाय django.urls.re_path() उपयोग करें django.urls.path()

पायथन नियमित अभिव्यक्तियों में, नामित नियमित अभिव्यक्ति समूहों के लिए वाक्यविन्यास है (?P<name>pattern) , जहां name समूह का name है और pattern मिलान करने के लिए कुछ पैटर्न है।

यहां पहले से दिए गए URLconf का उदाहरण दिया गया है, जो नियमित अभिव्यक्तियों का उपयोग करके फिर से लिखे गए हैं:

from django.urls import path, re_path

from . import views

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

यह पिछले उदाहरण के रूप में लगभग एक ही बात को पूरा करता है, सिवाय:

  • मिलान करने वाले सटीक URL थोड़े अधिक विवश हैं। उदाहरण के लिए, वर्ष 10000 अब मेल नहीं खाएगा क्योंकि वर्ष पूर्णांक चार अंक लंबे होने के लिए विवश हैं।
  • प्रत्येक कैप्चर किए गए तर्क को एक स्ट्रिंग के रूप में देखने के लिए भेजा जाता है, इस बात की परवाह किए बिना कि नियमित अभिव्यक्ति किस प्रकार का मेल बनाती है।

जब django.urls.path() का उपयोग करके django.urls.re_path() या इसके विपरीत पर स्विच किया जा रहा django.urls.path() , तो यह django.urls.re_path() विशेष रूप से महत्वपूर्ण है कि देखने के प्रकार के तर्क बदल सकते हैं, और इसलिए आपको अपने विचारों को अनुकूलित करने की आवश्यकता हो सकती है।

अनाम नियमित अभिव्यक्ति समूहों का उपयोग करना

साथ ही नामित समूह सिंटैक्स, उदा। (?P<year>[0-9]{4}) , आप छोटे अनाम समूह का भी उपयोग कर सकते हैं, उदाहरण के लिए ([0-9]{4})

इस उपयोग की विशेष रूप से अनुशंसा नहीं की जाती है क्योंकि यह गलती से मैच के इच्छित अर्थ और दृश्य के तर्कों के बीच त्रुटियों को प्रस्तुत करना आसान बनाता है।

किसी भी स्थिति में, दिए गए rexx के भीतर केवल एक शैली का उपयोग करने की सिफारिश की जाती है। जब दोनों शैलियों को मिलाया जाता है, तो किसी भी अनाम समूह को नजरअंदाज कर दिया जाता है और केवल नामित समूहों को दृश्य फ़ंक्शन में पास किया जाता है।

निहित तर्क

नियमित अभिव्यक्तियाँ नेस्टेड तर्क देती हैं, और Django उन्हें हल करेगा और उन्हें दृश्य में पास करेगा। पलटते समय, Django सभी बाहरी कैप्चर किए गए तर्कों को भरने की कोशिश करेगा, किसी भी नेस्टेड कैप्चर किए गए तर्कों को अनदेखा नहीं करेगा। निम्नलिखित URL पैटर्न पर विचार करें जो वैकल्पिक रूप से एक पृष्ठ तर्क लेते हैं:

from django.urls import re_path

urlpatterns = [
    re_path(r'^blog/(page-(\d+)/)?$', blog_articles),                  # bad
    re_path(r'^comments/(?:page-(?P<page_number>\d+)/)?$', comments),  # good
]

दोनों पैटर्न नेस्टेड तर्कों का उपयोग करते हैं और हल करेंगे: उदाहरण के लिए, blog/page-2/ परिणामस्वरूप blog_articles में दो blog_articles तर्कों के साथ मैच होगा: page-2/ और 2comments लिए दूसरा पैटर्न comments/page-2/ कीवर्ड तर्क के साथ page_number 2 पर सेट होगा। इस मामले में बाहरी तर्क एक गैर-कैप्चरिंग तर्क है (?:...)

blog_articles दृश्य को इस मामले में page-2/ या कोई तर्क देने के लिए सबसे बाहरी कैप्चर किए गए तर्क की आवश्यकता होती है, जबकि comments को page_number लिए कोई तर्क या मान के साथ नहीं page_number

नेस्टेड कैप्चर की गई blog_articles और URL के बीच एक मजबूत युग्मन का निर्माण करती हैं, जैसा कि blog_articles द्वारा सचित्र किया blog_articles : दृश्य URL ( page-2/ ) का हिस्सा प्राप्त करता है, बजाय इसके कि केवल जिस दृश्य में रुचि है, यह युग्म अधिक स्पष्ट है। उलटा करने के बाद, दृश्य को उलटने के लिए हमें पृष्ठ संख्या के बजाय URL के टुकड़े को पास करना होगा।

अंगूठे के एक नियम के रूप में, केवल उन मूल्यों को कैप्चर करते हैं जिन्हें देखने के लिए काम करने की आवश्यकता होती है और गैर-कैप्चरिंग तर्कों का उपयोग करते हैं जब नियमित अभिव्यक्ति को एक तर्क की आवश्यकता होती है लेकिन दृश्य इसे अनदेखा करता है।

URLconf के खिलाफ क्या खोज करता है

URLconf अनुरोधित URL के विरुद्ध सामान्य पायथन स्ट्रिंग के रूप में खोज करता है। इसमें GET या POST पैरामीटर या डोमेन नाम शामिल नहीं है।

उदाहरण के लिए, https://www.example.com/myapp/ अनुरोध में, URLconf myapp/ लिए दिखेगा।

https://www.example.com/myapp/?page=3 अनुरोध में, URLconf myapp/ लिए दिखेगा।

URLconf अनुरोध विधि को नहीं देखता है। दूसरे शब्दों में, सभी अनुरोध विधियां - POST , GET , HEAD , आदि - समान URL के लिए एक ही फ़ंक्शन में रूट की जाएंगी।

दृश्य तर्कों के लिए डिफॉल्ट निर्दिष्ट करना

एक सुविधाजनक चाल अपने विचारों के तर्कों के लिए डिफ़ॉल्ट पैरामीटर निर्दिष्ट करना है। यहां एक उदाहरण URLconf और देखें:

# URLconf
from django.urls import path

from . import views

urlpatterns = [
    path('blog/', views.page),
    path('blog/page<int:num>/', views.page),
]

# View (in blog/views.py)
def page(request, num=1):
    # Output the appropriate page of blog entries, according to num.
    ...

उपरोक्त उदाहरण में, दोनों URL पैटर्न एक ही दृश्य - views.page - को इंगित करते हैं, लेकिन पहला पैटर्न URL से कुछ भी कैप्चर नहीं करता है। यदि पहला पैटर्न मेल खाता है, तो page() फ़ंक्शन num , 1 लिए अपने डिफ़ॉल्ट तर्क का उपयोग करेगा। यदि दूसरा पैटर्न मैच करता है, तो page() का उपयोग किया जाएगा जो भी num मूल्य पर कब्जा कर लिया गया था।

प्रदर्शन

urlpatterns में प्रत्येक नियमित अभिव्यक्ति को पहली बार एक्सेस किए जाने पर संकलित किया जाता है। यह सिस्टम को धधकते हुए तेज बनाता है।

urlpatterns चर का सिंटैक्स

urlpatterns django.urls.path() और / या django.urls.re_path() उदाहरणों की पायथन सूची होनी चाहिए।

गलती संभालना

जब Django अनुरोधित URL के लिए एक मैच नहीं मिल सकता है, या जब एक अपवाद उठाया जाता है, तो Django त्रुटि-हैंडलिंग दृश्य को आमंत्रित करता है।

इन मामलों के लिए उपयोग किए जाने वाले विचार चार चर द्वारा निर्दिष्ट किए गए हैं। उनके डिफ़ॉल्ट मूल्यों को अधिकांश परियोजनाओं के लिए पर्याप्त होना चाहिए, लेकिन उनके डिफ़ॉल्ट मूल्यों को ओवरराइड करके आगे अनुकूलन संभव है।

पूर्ण विवरण के लिए त्रुटि विचारों को अनुकूलित करने पर प्रलेखन देखें।

ऐसे मान आपके रूट URLconf में सेट किए जा सकते हैं। इन चरों को किसी अन्य URLconf में सेट करने से कोई प्रभाव नहीं पड़ेगा।

मान कॉलिबल या स्ट्रिंग्स होना चाहिए, यह देखने के लिए पूर्ण पायथन आयात पथ का प्रतिनिधित्व करता है जिसे हाथ में त्रुटि स्थिति को संभालने के लिए बुलाया जाना चाहिए।

चर हैं:

  • handler400 - handler400 देखें।
  • handler403 - handler403 देखें।
  • handler404 - देखें django.conf.urls.handler404
  • handler500 - handler500 देखें।

सहित अन्य URLconfs

किसी भी बिंदु पर, आपके urlpatterns अन्य URLconf मॉड्यूल को "शामिल" कर सकते हैं। यह अनिवार्य रूप से "रूट" अन्य लोगों के नीचे URL का एक सेट है।

उदाहरण के लिए, यहाँ Django वेबसाइट के लिए URLconf का एक अंश है। इसमें कई अन्य URLconfs शामिल हैं:

from django.urls import include, path

urlpatterns = [
    # ... snip ...
    path('community/', include('aggregator.urls')),
    path('contact/', include('contact.urls')),
    # ... snip ...
]

जब भी Django के मुकाबलों include() , यह उस बिंदु तक मेल खाने वाले URL के किसी भी हिस्से को काट देता है और शेष स्ट्रिंग को आगे की प्रक्रिया के लिए शामिल URLconf में भेज देता है।

एक अन्य संभावना django.urls.path() सूची django.urls.path() उदाहरणों का उपयोग करके अतिरिक्त URL पैटर्न शामिल करना है। उदाहरण के लिए, इस URLconf पर विचार करें:

from django.urls import include, path

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    path('reports/', credit_views.report),
    path('reports/<int:id>/', credit_views.report),
    path('charge/', credit_views.charge),
]

urlpatterns = [
    path('', main_views.homepage),
    path('help/', include('apps.help.urls')),
    path('credit/', include(extra_patterns)),
]

इस उदाहरण में, /credit/reports/ URL को credit_views.report() Django दृश्य द्वारा नियंत्रित किया जाएगा।

इसका उपयोग URLconfs से अतिरेक को दूर करने के लिए किया जा सकता है जहां एकल पैटर्न उपसर्ग का बार-बार उपयोग किया जाता है। उदाहरण के लिए, इस URLconf पर विचार करें:

from django.urls import path
from . import views

urlpatterns = [
    path('<page_slug>-<page_id>/history/', views.history),
    path('<page_slug>-<page_id>/edit/', views.edit),
    path('<page_slug>-<page_id>/discuss/', views.discuss),
    path('<page_slug>-<page_id>/permissions/', views.permissions),
]

हम केवल एक बार सामान्य पथ उपसर्ग को बताते हुए और प्रत्ययों को अलग करते हुए इसमें सुधार कर सकते हैं:

from django.urls import include, path
from . import views

urlpatterns = [
    path('<page_slug>-<page_id>/', include([
        path('history/', views.history),
        path('edit/', views.edit),
        path('discuss/', views.discuss),
        path('permissions/', views.permissions),
    ])),
]

मापदंडों पर कब्जा कर लिया

शामिल URLconf को मूल URLconfs से कोई भी कैप्चर किया गया पैरामीटर प्राप्त होता है, इसलिए निम्न उदाहरण मान्य है:

# In settings/urls/main.py
from django.urls import include, path

urlpatterns = [
    path('<username>/blog/', include('foo.urls.blog')),
]

# In foo/urls/blog.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.blog.index),
    path('archive/', views.blog.archive),
]

उपरोक्त उदाहरण में, कैप्चर किए गए "username" चर को अपेक्षित URL के रूप में शामिल किया गया है।

कार्यों को देखने के लिए अतिरिक्त विकल्प पास करना

URLconfs में एक हुक है जो आपको पायथन डिक्शनरी के रूप में आपके दृश्य कार्यों के लिए अतिरिक्त तर्क देने की अनुमति देता है।

django.urls.path() फ़ंक्शन एक वैकल्पिक तीसरा तर्क ले सकता है जो दृश्य फ़ंक्शन को पास करने के लिए अतिरिक्त कीवर्ड तर्क का शब्दकोश होना चाहिए।

उदाहरण के लिए:

from django.urls import path
from . import views

urlpatterns = [
    path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}),
]

इस उदाहरण में, /blog/2005/ लिए एक अनुरोध के लिए, Django के विचार कहेंगे views.year_archive(request, year=2005, foo='bar')

इस तकनीक का उपयोग सिंडिकेशन फ्रेमवर्क में मेटाडेटा और विचारों के विकल्पों को पारित करने के लिए किया जाता है।

संघर्षों से निपटना

ऐसा URL पैटर्न होना संभव है जो कीवर्ड तर्कों को कैप्चर करता है, और अतिरिक्त तर्कों के शब्दकोश में समान नामों के साथ तर्क भी पास करता है। जब ऐसा होता है, तो URL में कैप्चर किए गए तर्कों के बजाय शब्दकोश में दिए गए तर्कों का उपयोग किया जाएगा।

include() करने के लिए अतिरिक्त विकल्प पास करना include()

इसी तरह, आप include() करने के लिए अतिरिक्त विकल्प पास कर सकते include() और शामिल URLconf में प्रत्येक पंक्ति अतिरिक्त विकल्प पारित किया जाएगा।

उदाहरण के लिए, ये दो URLconf सेट कार्यात्मक रूप से समान हैं:

एक सेट करें:

# main.py
from django.urls import include, path

urlpatterns = [
    path('blog/', include('inner'), {'blog_id': 3}),
]

# inner.py
from django.urls import path
from mysite import views

urlpatterns = [
    path('archive/', views.archive),
    path('about/', views.about),
]

दो सेट करें:

# main.py
from django.urls import include, path
from mysite import views

urlpatterns = [
    path('blog/', include('inner')),
]

# inner.py
from django.urls import path

urlpatterns = [
    path('archive/', views.archive, {'blog_id': 3}),
    path('about/', views.about, {'blog_id': 3}),
]

ध्यान दें कि अतिरिक्त विकल्प हमेशा शामिल URLconf में हर पंक्ति के लिए दिए जाएंगे, चाहे रेखा का दृश्य वास्तव में उन विकल्पों को मान्य मानता हो या नहीं। इस कारण से, यह तकनीक केवल तभी उपयोगी है जब आप निश्चित हों कि शामिल URLconf में प्रत्येक दृश्य आपके द्वारा पास किए जा रहे अतिरिक्त विकल्पों को स्वीकार करता है।

URL का उल्टा रिज़ॉल्यूशन

एक Django परियोजना पर काम करते समय एक आम जरूरत है कि उनके अंतिम रूपों में URL प्राप्त करने की संभावना उत्पन्न सामग्री (विचार और संपत्ति URL, उपयोगकर्ता को दिखाए गए URL आदि) में एम्बेड करने के लिए या सर्वर पर नेविगेशन प्रवाह को संभालने के लिए है। पक्ष (पुनर्निर्देशन, आदि)

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

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

URL प्राप्त करने के लिए हमारे पास उपलब्ध जानकारी का प्राथमिक टुकड़ा इसे संभालने के प्रभारी के दृश्य की एक पहचान (जैसे नाम) है। सही URL को देखने के लिए आवश्यक जानकारी के अन्य टुकड़े प्रकार (स्थिति, कीवर्ड) और देखने के तर्क के मान हैं।

Django एक समाधान प्रदान करता है जैसे कि URL मैपर URL डिज़ाइन का एकमात्र भंडार है। आप इसे अपने URLconf के साथ फीड करते हैं और फिर इसे दोनों दिशाओं में उपयोग किया जा सकता है:

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

पहला वह उपयोग है जिसके बारे में हम पिछले अनुभागों में चर्चा कर चुके हैं। दूसरा वह है जिसे URL के रिवर्स रिज़ॉल्यूशन , रिवर्स URL मिलान , रिवर्स URL लुकअप या बस URL रिवर्सिंग के रूप में जाना जाता है।

Django URL के प्रदर्शन के लिए उपकरण प्रदान करता है जो URL की आवश्यकता वाली विभिन्न परतों से मेल खाता है:

  • टेम्प्लेट में: url टेम्पलेट टैग का उपयोग करना।
  • पायथन कोड में: reverse() फ़ंक्शन का उपयोग करना।
  • Django मॉडल उदाहरणों के URL से संबंधित उच्च स्तरीय कोड में: get_absolute_url() विधि।

उदाहरण

इस URLconf प्रविष्टि पर फिर से विचार करें:

from django.urls import path

from . import views

urlpatterns = [
    #...
    path('articles/<int:year>/', views.year_archive, name='news-year-archive'),
    #...
]

इस डिजाइन के अनुसार, वर्ष nnnn के लिए संग्रह के लिए URL /articles/<nnnn>/

आप इनका उपयोग करके टेम्पलेट कोड में प्राप्त कर सकते हैं:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

या पायथन कोड में:

from django.http import HttpResponseRedirect
from django.urls import reverse

def redirect_to_year(request):
    # ...
    year = 2006
    # ...
    return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

यदि, किसी कारण से, यह निर्णय लिया गया कि जिन URL पर वार्षिक लेख संग्रह के लिए सामग्री प्रकाशित की जाती है, उन्हें बदल दिया जाना चाहिए, तो आपको केवल URLconf में प्रविष्टि को बदलने की आवश्यकता होगी।

कुछ परिदृश्यों में जहां दृश्य एक सामान्य प्रकृति के होते हैं, URL और विचारों के बीच कई-से-एक संबंध मौजूद हो सकते हैं। इन मामलों के लिए जब URL को पलटने का समय आता है तो दृश्य नाम इसके लिए एक अच्छा पहचानकर्ता नहीं होता है। Django इस के लिए समाधान प्रदान करता है के बारे में जानने के लिए अगला भाग पढ़ें।

नामकरण URL पैटर्न

URL रिवर्सल करने के लिए, आपको ऊपर दिए गए उदाहरणों में किए गए URL पैटर्न का उपयोग करना होगा। URL नाम के लिए उपयोग की जाने वाली स्ट्रिंग में आपके पसंद के कोई भी अक्षर हो सकते हैं। आप मान्य पायथन नामों तक सीमित नहीं हैं।

URL पैटर्न का नामकरण करते समय, उन नामों को चुनें, जो अन्य एप्लिकेशन के नामों की पसंद के साथ टकराव की संभावना नहीं रखते हैं। यदि आप अपने URL पैटर्न comment और एक अन्य अनुप्रयोग एक ही काम करता है, जो URL reverse() पाता है जो भी आपके प्रोजेक्ट की urlpatterns सूची में अंतिम है।

अपने URL नामों पर एक उपसर्ग लगाते हुए, शायद एप्लिकेशन नाम (जैसे कि myapp-comment बजाय myapp-comment comment ) से लिया गया है, टकराव की संभावना को कम करता है।

यदि आप किसी दृश्य को ओवरराइड करना चाहते हैं तो आप जानबूझकर उसी URL नाम को किसी अन्य एप्लिकेशन के रूप में चुन सकते हैं। उदाहरण के लिए, एक सामान्य उपयोग मामला LoginView को ओवरराइड करने के लिए है। Django और अधिकांश तृतीय-पक्ष एप्लिकेशन के कुछ हिस्सों का मानना ​​है कि इस दृश्य में login नाम के साथ एक URL पैटर्न है। यदि आपके पास एक कस्टम लॉगिन दृश्य है और इसके URL को नाम login , तो reverse() urlpatterns बाद django.contrib.auth.urls में शामिल है (जब तक कि यह सब शामिल है) तब तक आपका कस्टम दृश्य मिल जाएगा।

यदि आप उनके तर्क में भिन्न होते हैं, तो आप एकाधिक URL पैटर्न के लिए एक ही नाम का उपयोग कर सकते हैं। URL नाम के अलावा, reverse() तर्कों की संख्या और कीवर्ड तर्कों के नामों से मेल खाता है।

URL नामस्थान

परिचय

URL नेमस्पेस आपको नामांकित URL पैटर्न को विशिष्ट रूप से रिवर्स करने की अनुमति देता है, भले ही विभिन्न एप्लिकेशन एक ही URL नामों का उपयोग करते हों। थर्ड-पार्टी ऐप्स के लिए हमेशा नाम-आधारित URL (जैसा कि हमने ट्यूटोरियल में किया था) का उपयोग करना एक अच्छा अभ्यास है। इसी तरह, यदि आप किसी एप्लिकेशन के कई इंस्टेंसेस परिनियोजित हैं, तो यह आपको URL को उलटने की अनुमति देता है। दूसरे शब्दों में, चूंकि एकल एप्लिकेशन के कई उदाहरण URL नाम साझा करेंगे, इसलिए नामस्थान इन नामांकित URL को अलग से बताने का एक तरीका प्रदान करते हैं।

Django अनुप्रयोग जो URL नामस्थान का उचित उपयोग करते हैं, उन्हें किसी विशेष साइट के लिए एक से अधिक बार तैनात किया जा सकता है। उदाहरण के लिए django.contrib.admin में एक AdminSite वर्ग है जो आपको आसानी से व्यवस्थापक के एक से अधिक उदाहरणों को तैनात करने की अनुमति देता है। बाद के उदाहरण में, हम दो अलग-अलग स्थानों में ट्यूटोरियल से चुनाव के आवेदन को लागू करने के विचार पर चर्चा करेंगे ताकि हम एक ही कार्यक्षमता को दो अलग-अलग दर्शकों (लेखकों और प्रकाशकों) को परोस सकें।

एक URL नेमस्पेस दो भागों में आता है, दोनों ही तार हैं:

application namespace
यह उस एप्लिकेशन के नाम का वर्णन करता है जिसे तैनात किया जा रहा है। किसी एकल एप्लिकेशन के प्रत्येक उदाहरण में एक ही एप्लिकेशन नामस्थान होगा। उदाहरण के लिए, Django के एडमिन एप्लिकेशन में 'admin' का कुछ प्रेडिक्टेबल एप्लिकेशन नेमस्पेस है।
instance namespace
यह किसी एप्लिकेशन के विशिष्ट उदाहरण की पहचान करता है। इंस्टेंस नेमस्पेस आपके पूरे प्रोजेक्ट में अद्वितीय होना चाहिए। हालाँकि, एक नाम नामस्थान अनुप्रयोग नामस्थान के समान हो सकता है। इसका उपयोग किसी एप्लिकेशन के डिफ़ॉल्ट उदाहरण को निर्दिष्ट करने के लिए किया जाता है। उदाहरण के लिए, डिफ़ॉल्ट Django व्यवस्थापक उदाहरण में 'admin' का एक उदाहरण नामस्थान है।

नाम URL को ':' ऑपरेटर के उपयोग से निर्दिष्ट किया जाता है। उदाहरण के लिए, एडमिन एप्लिकेशन के मुख्य इंडेक्स पेज को 'admin:index' का उपयोग करके संदर्भित किया जाता है। यह 'admin' एक नामस्थान और 'index' एक नामांकित URL को इंगित करता है।

Namespaces को नेस्टेड भी किया जा सकता है। नामांकित URL 'sports:polls:index' नाम स्थान 'polls' में 'index' नाम के एक पैटर्न की तलाश करेगा, जो कि स्वयं को शीर्ष-स्तरीय नामस्थान 'sports' परिभाषित किया गया है।

नाम स्थान URL को उलट देना

हल करने के लिए एक नामांकित URL (उदाहरण के लिए 'polls:index' ) दिए जाने पर, Django पूरी तरह से योग्य नाम को भागों में विभाजित करता है और फिर निम्नलिखित लुकअप को आज़माता है:

  1. सबसे पहले, Django एक मिलान अनुप्रयोग नामस्थान की खोज करता है (इस उदाहरण में, 'polls' )। इससे उस एप्लिकेशन के उदाहरणों की एक सूची प्राप्त होगी।
  2. यदि कोई वर्तमान एप्लिकेशन निर्धारित है, तो Django उस उदाहरण के लिए URL रिज़ॉल्वर पाता है और उसे लौटाता है। वर्तमान एप्लिकेशन को reverse() फ़ंक्शन के लिए current_app तर्क के साथ निर्दिष्ट किया जा सकता है।

    url टेम्प्लेट टैग वर्तमान में हल किए गए दृश्य के नाम स्थान का उपयोग एक RequestContext में वर्तमान एप्लिकेशन के रूप में करता है। आप कर सकते हैं ओवरराइड करें इस डिफ़ॉल्ट को वर्तमान एप्लिकेशन को request.current_app विशेषता पर सेट करके।

  3. यदि कोई वर्तमान एप्लिकेशन नहीं है, तो Django डिफ़ॉल्ट एप्लिकेशन इंस्टेंस की तलाश करता है। डिफ़ॉल्ट अनुप्रयोग उदाहरण वह उदाहरण है जिसमें अनुप्रयोग नामस्थान (इस उदाहरण में, 'polls' कहे जाने वाले polls उदाहरण) से मेल खाते हुए एक उदाहरण नेमस्पेस होता है
  4. यदि कोई डिफ़ॉल्ट एप्लिकेशन इंस्टेंस नहीं है, तो Django एप्लिकेशन के अंतिम तैनात किए गए इंस्टेंस को चुन लेगा, जो भी उसका इंस्टेंस नाम हो सकता है।
  5. यदि उपलब्ध नामस्थान चरण 1 में एक अनुप्रयोग नामस्थान से मेल नहीं खाता है, तो Django एक उदाहरण नामस्थान के रूप में नामस्थान के प्रत्यक्ष लुकअप का प्रयास करेगा।

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

उदाहरण

कार्रवाई में इस रिज़ॉल्यूशन रणनीति को दिखाने के लिए, ट्यूटोरियल से polls आवेदन के दो उदाहरणों पर एक उदाहरण पर विचार करें: एक को 'author-polls' और एक को 'publisher-polls' कहा जाता है। मान लें कि हमने उस एप्लिकेशन को बढ़ा दिया है, ताकि पोल बनाते और प्रदर्शित करते समय उदाहरण नामस्थान को ध्यान में रखा जाए।

from django.urls import include, path

urlpatterns = [
    path('author-polls/', include('polls.urls', namespace='author-polls')),
    path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]
from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    ...
]

इस सेटअप का उपयोग करते हुए, निम्नलिखित लुकअप संभव हैं:

  • यदि उदाहरणों में से एक चालू है - कहो, यदि हम उदाहरण पृष्ठ को 'author-polls' में प्रस्तुत कर रहे थे - 'polls:index' 'author-polls' उदाहरण के सूचकांक पृष्ठ को हल करेगा; अर्थात निम्नलिखित दोनों का परिणाम "/author-polls/"

    क्लास-आधारित दृश्य की विधि में:

    reverse('polls:index', current_app=self.request.resolver_match.namespace)
    

    और टेम्पलेट में:

    {% url 'polls:index' %}
    
  • यदि कोई वर्तमान उदाहरण नहीं है - कहो, यदि हम साइट पर कहीं और एक पृष्ठ प्रदान कर रहे थे - 'polls:index' के अंतिम पंजीकृत उदाहरण का समाधान करेगा। चूंकि कोई डिफ़ॉल्ट उदाहरण ( 'polls' का नाम स्थान) नहीं है, इसलिए पंजीकृत होने वाले polls के अंतिम उदाहरण का उपयोग किया जाएगा। यह 'publisher-polls' क्योंकि यह urlpatterns में अंतिम घोषित किया गया है।
  • 'author-polls:index' हमेशा 'author-polls' (और 'publisher-polls' लिए इसी तरह) के इंडेक्स पेज को हल करेगा।

यदि कोई डिफ़ॉल्ट उदाहरण भी था - यानी, 'polls' नामक एक उदाहरण - ऊपर से एकमात्र परिवर्तन उस स्थिति में होगा जहां कोई वर्तमान उदाहरण नहीं है (ऊपर की सूची में दूसरा आइटम)। इस मामले में 'polls:index' urlpatterns में अंतिम घोषित किए गए इंस्टेंस के बजाय डिफ़ॉल्ट इंस्टेंस के इंडेक्स पेज को हल करेगा।

URL नामस्थान और शामिल URLconfs

शामिल URLconfs के अनुप्रयोग नामस्थान दो तरीकों से निर्दिष्ट किए जा सकते हैं।

सबसे पहले, आप app_name विशेषता के समान स्तर पर शामिल URLconf मॉड्यूल में एक app_name विशेषता सेट कर सकते हैं। आपको शामिल करने के लिए वास्तविक मॉड्यूल, या मॉड्यूल के एक स्ट्रिंग संदर्भ को पास करना होगा include() , खुद urlpatterns की सूची नहीं।

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    ...
]
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
]

polls.urls में परिभाषित URL में एक एप्लिकेशन नेमस्पेस polls

दूसरे, आप एक ऑब्जेक्ट शामिल कर सकते हैं जिसमें एम्बेडेड नेमस्पेस डेटा शामिल है। यदि आप django.urls.path() सूची django.urls.path() या django.urls.re_path() इंस्टेंस शामिल करते हैं, तो उस ऑब्जेक्ट में शामिल URL वैश्विक नामस्थान में जोड़े जाएंगे। हालाँकि, आप भी include() कर सकते include() एक 2-टपल युक्त:

(<list of path()/re_path() instances>, <application namespace>)

उदाहरण के लिए:

from django.urls import include, path

from . import views

polls_patterns = ([
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
], 'polls')

urlpatterns = [
    path('polls/', include(polls_patterns)),
]

इसमें दिए गए एप्लिकेशन नामस्थान में नामांकित URL पैटर्न शामिल होंगे।

उदाहरण नामस्थान को include() करने के लिए namespace तर्क का उपयोग करके निर्दिष्ट किया जा सकता है include() । यदि उदाहरण नाम स्थान निर्दिष्ट नहीं है, तो यह शामिल URLconf के एप्लिकेशन नाम स्थान पर डिफ़ॉल्ट होगा। इसका मतलब यह है कि यह उस नाम स्थान के लिए डिफ़ॉल्ट उदाहरण भी होगा।