SoFunction
Updated on 2024-12-11

Django's Routing Layer Implementation

The URL configuration (URLconf) is like a directory for the site Django is hosting. It's meant to be a table of mappings between URLs and the view functions to be called for those URLs, and it's how you tell Django which piece of logic to call for a particular URL from a client.

I. Simple Routing Configuration

from  import path,re_path

from app01 import views

urlpatterns = [
re_path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

Note: To capture a value from a URL, simply place a pair of parentheses around it. There is no need to add a leading backslash, as every URL has one. For example, it should be ^articles instead of ^/articles. The r in front of each regular expression is optional, but recommended, as it tells Python that the string is "raw" - no characters in the string should be escaped.

Some examples of requests:

The /articles/2005/03/ request will match the third pattern in the list.Django will call the function views.month_archive(request, '2005', '03').
/articles/2005/3/ doesn't match any URL patterns because the third pattern in the list requires that the month should be two numbers.
/articles/2003/ will match the first pattern in the list not the second because the patterns are matched in order and the first one will be tested for a match first. Please feel free to insert some special cases like this to detect the order of matches.
/articles/2003 does not match any of the patterns because each pattern requires the URL to end with a backslash.
/articles/2003/03/03/ will match the last pattern.Django will call the function views.article_detail(request, '2003', '03', '03').

II. Named subgroups

The above example uses a simple, unnamed regular expression (via parentheses) to capture the value in the URL and pass it to the view as a positional parameter. In more advanced usage, a named regular expression group can be used to capture the value in the URL and pass it to the view as a keyword argument. In Python regular expressions, the syntax for a named regular expression group is (?P<name>pattern), where name is the name of the group and pattern is the pattern to match. Here is a rewrite of the above URLconf using named groups:

from  import path,re_path

from app01 import views

urlpatterns = [
re_path(r'^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<day>[0-9]{2})/$', views.article_detail),
]

This implementation is identical to the previous example, with one minor difference: the captured value is passed to the view function as a keyword parameter instead of a positional parameter. Example:

/articles/2005/03/ The request will call theviews.month_archive(request, year='2005', month='03')function (math.),rather thanviews.month_archive(request, '2005', '03')。
/articles/2003/03/03/ The request will call the functionviews.article_detail(request, year='2003', month='03', day='03')。

III. Distribution

'''
At any point, your urlpatterns can “include” other URLconf modules. This
essentially “roots” a set of URLs below other ones.
'''

from  import path,re_path,include
from app01 import views

urlpatterns = [
re_path(r'^admin/', ),
re_path(r'^blog/', include('')),
]

IV. Reverse parsing

A common requirement when working with Django projects is to obtain the final form of URLs for embedding into generated content (URLs in views and displayed to users, etc.) or for handling server-side navigation (redirects, etc.). There is a strong preference not to hard-code these URLs (laborious, non-extensible, and error-prone) or to design a specialized URL generation mechanism unrelated to URLconf, which tends to result in a certain amount of out-of-date URLs, and where URLs are needed, Django provides different amounts of tooling for URL rechecking at different levels:

1、在模板中:使用URLTemplate Tags。

2. In Python code: use the from import reverse function :

from  import url

from . import views

urlpatterns = [
#...
re_path(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
#...
]

in the template:

<a href="{% url 'news-year-archive' 2012 %}" rel="external nofollow" >2012 Archive</a>

<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}" rel="external nofollow" >{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

In python:

from  import reverse
from  import HttpResponseRedirect

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

When naming your URL pattern, make sure to use a name that does not conflict with a name in another application. If your URL pattern is called comment and another app has the same name, there is no guarantee which URL will be inserted when you use that name in a template. adding a prefix to the URL name, such as the name of the app, will reduce the possibility of conflicts. We recommend using myapp-comment instead of comment.

V. Namespace

Namespace is the visible scope of an identifier. An identifier can be defined in more than one namespace, and its meaning in different namespaces is disjoint. Thus, any identifier can be defined in a new namespace, and they won't conflict with any existing identifiers, because the existing definitions are in other namespaces. Since name has no scope, Django searches the project's global order when decomposing URLs and returns the first name-specified URL as soon as it is found. We will often use the name attribute to disambiguate URLs when developing projects. When the same name is accidentally defined in the urls of different apps, it may lead to URL disambiguation errors, and in order to avoid this, namespaces have been introduced.

In the middle of the project:

urlpatterns = [
re_path(r'^admin/', ),
re_path(r'^app01/', include(("",namespace="app01"))),
re_path(r'^app02/', include(("",namespace="app02"))),
]

:

urlpatterns = [
re_path(r'^index/', index,name="index"),
]

:

urlpatterns = [
re_path(r'^index/', index,name="index"),
]

:

from  import reverse
def index(request):
  return HttpResponse(reverse("app01:index"))

:

from  import reverse
def index(request):
  return HttpResponse(reverse("app02:index"))

VI. Django2.0 version of the path

urlpatterns = [
re_path('articles/(?P<year>[0-9]{4})/', year_archive),
re_path('article/(?P<article_id>[a-zA-Z0-9]+)/detail/', detail_view),
re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/edit/', edit_view),
re_path('articles/(?P<article_id>[a-zA-Z0-9]+)/delete/', delete_view),
]

Consider two such questions:

1, function year_archive in the year parameter is a string type, so you need to be converted to an integer type of variable value, of course, year = int (year) will not have such as TypeError or VaError exception. So is there a way, in the url, to make this conversion step can be done automatically by Django?

2, three routes in the article_id rule change, you need to modify three code at the same time, then there is a way, only need to modify a can?

In Django version 2.0, you can use path to solve the above two problems.

Simple Example:

from  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>/', views.article_detail), 
]

Ground rules:

1. Use pointed brackets <> to capture the value from the url.

2, the capture value can include a converter type (converter type), such as using & lt; int : name & gt; capture an integer variable. If there is no converter, it will match any string, including, of course, the / character.

3. There is no need to add a leading slash.

The following is based on/en/2.0/topics/http/urls/#exampleAnd the example analysis table that was put together:

path converter:

The original document is Path converters, tentatively translated as converters.

Django supports the following 5 converters by default:

1, str -- match the non-empty string except path separator /, which is the default form.

2. int - matches positive integers, including 0.

3、slug——匹配字母、数字以及横杠、underscore string。

4. uuid - match the formatted uuid, such as 075194d3-6885-417e-a8a8-6c931e272f00.

5, path - matches any non-empty string that contains a path separator.

Register the custom converter:

For some complex or reusable needs, you can define your own converter.

A converter is a class or interface that has three requirements:

1. regex class attribute, string type.

2, to_python (self, value) method, value is matched by the class attribute regex string did not return a specific Python variable value for Django to pass to the corresponding view function.

3, to_url (self, value) method, and to_python the opposite, value is a specific Python variable value, return its string, usually used for url reverse reference.

Example:

class FourDigitYearConverter: 
  regex = '[0-9]{4}' 
  def to_python(self, value): 
    return int(value) 
  def to_url(self, value): 
    return '%04d' % value

Use register_converter to register it to the URL configuration:

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

This is the whole content of this article.