Django's routing system

Keywords: Django Python

Catalog

One: URLconf configuration

(I): basic format

(II): parameter description

Two: regular expression usage analysis

(I): basic configuration

(II): precautions

Three: group name matching

(I): location of URLconf matching

(2): the captured parameters are always strings

(3): default value specified in view function

(IV): include other URLconfs

Four: passing extra parameters to view function

V: named URL and URL reverse parsing

(I): concept description

(II): Example

VI: namespace mode

Django1.11 route officialTo configureFile

Django 2.0 routing official configuration document

One: URLconf configuration

(I): basic format

from django.conf.urls import url

urlpatterns = [
     url(regular expression , views View function, parameter, alias),
]

Note: the routing system in Django version 2.0 has been replaced with the following

from django.urls import path

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),
]

(II): parameter description

  • Regular expression: a regular expression string
  • views view function: a callable object, usually a view function or a string specifying the path of the view function
  • Parameters: optional default parameters (in dictionary form) to pass to view functions
  • Alias: an optional name parameter

Two: regular expression usage analysis

(I): basic configuration

from django.conf.urls import url

from . import views

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

(II): precautions

  1. The elements in urlpatterns match the regular expressions one by one from top to bottom in writing order. Once the matching is successful, it will not continue.
  2. To capture a value from a URL, simply place a pair of parentheses around it (grouped match).
  3. You don't need to add a leading backslash because each URL has one. For example, it should be ^ articles instead of ^ / articles.
  4. The 'r' before each regular expression is optional but recommended.

Supplement:

# Whether to enable the configuration item that does not jump to the path with / after the URL access address
APPEND_SLASH=True

Django settings.py configuration file does not have the parameter APPEND_SLASH by default, but Django defaults to APPEND_SLASH = True. Its function is to automatically add '/' at the end of the URL.

The effect is:

We defined urls.py:

from django.conf.urls import url
from app01 import views

urlpatterns = [
        url(r'^blog/$', views.blog),
]

When visiting http://www.example.com/blog, the web address is automatically converted to http://www.example/com/blog/ by default.

If append? Slash = false is set in settings.py, when we request http://www.example.com/blog, we will be prompted that the page cannot be found.

Three: group name matching

The above example uses a simple regular expression grouping match (through parentheses) to capture the value in the URL and pass it to the view as a positional parameter. In a more advanced use, you can use groups of regular expressions that name matches to capture the values in the URL and pass them to the view as key parameters. In Python regular expressions, the syntax of grouping and naming regular expression groups is (? P < name > pattern), where name is the name of the group and pattern is the pattern to match.

The following are the overrides of the above URLconf using named groups:

from django.conf.urls import url

from . import views

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

This implementation is exactly the same as the previous example, with only one slight difference: the captured value is passed to the view function as a key parameter instead of a location parameter.

For example, for url / articles/2017/12 /, it is equivalent to calling the view function as follows:

views.month_archive(request, year="2017", month="12")

In practical application, using group name matching method can make your URLconf more clear and not easy to produce error of parameter order.

(I): location of URLconf matching

URLconf looks up the requested URL as a normal Python string. GET and POST parameters and domain names are not included.

For example, in the http://www.example.com/myapp/ request, URLconf will look for myapp /.

In the http://www.example.com/myapp/?page=3 request, URLconf will still look for myapp /.

URLconf does not check the requested method. In other words, all request methods -- POST, GET, HEAD, and so on for the same URL -- will be routed to the same function

(2): the captured parameters are always strings

Each parameter captured in URLconf is passed to the view as a normal Python string, regardless of the matching method used by the regular expression. For example, in the following line, URLconf:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

The year parameter passed to the view function views. Year? Archive(), is always a string type.

(3): default value specified in view function

# urls.py medium
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# In views.py, you can specify a default value for num
def page(request, num="1"):
    pass

In the example above, the two URL patterns point to the same view - views.page - but the first pattern does not capture anything from the URL. If the first pattern matches, the page() function uses its default parameter num = "1"; if the second pattern matches, the page() function uses the num value captured by the regular expression.

(IV): include other URLconfs

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

#For example, here's an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:


from django.conf.urls import include, url

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^blog/', include('blog.urls')),  # Other urlconf files can be included
]

Four: passing extra parameters to view function

URLconfs has a hook that lets you pass a Python dictionary as an additional parameter to the view function. The django.conf.urls.url() - function can receive an optional third parameter, which is a dictionary that represents additional keyword parameters that you want to pass to the view function.

For example:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

In this case, for the / blog/2005 / request, Django will call views.year_archive(request, year='2005', foo='bar'). This technology is used in the Syndication framework to pass metadata and options to views.

V: named URL and URL reverse parsing

(I): concept description

Our URL matching rule starts with a name, and a URL matching pattern starts with a name. In this way, we don't need to write dead URL code in the future. We just need to call the current URL by name.

Django provides a way to make URL mapping the only place for URL design. You populate your URLconf and then use it in both directions:

  • Based on the URL request initiated by the user / browser, it calls the correct Django view and extracts the required values of its parameters from the URL.
  • Gets the URL associated with the Django view based on its identity and the value of the parameter to be passed to it.

Where a URL is needed, Django provides different tools for URL retrieval at different levels:

  • In template: use the url template label.
  • In Python code: use the django.core.urlresolvers.reverse() function.
  • In the higher-level code related to handling Django model instances: use the get uubsolute uurl() method.

Take a simple example:

url(r'^home', views.home, name='home'),  # Name my url matching pattern home
url(r'^index/(\d*)', views.index, name='index'),  # Name my url matching pattern index

You can reference it in the template as follows:

{% url 'home' %}

You can reference this in the views function:

from django.urls import reverse

reverse("index", args=("2018", ))

(II): Example

from django.conf.urls import url

from . import views

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

According to the design here, the URL of the archive corresponding to nnnn in a certain year is / articles/nnnn /.

In the code of the template, use this:

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

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

In Python code, use this:

from django.urls import reverse
from django.shortcuts import redirect

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

VI: namespace mode

Even if different apps use the same URL name, the namespace pattern of the URL allows you to uniquely reverse the named URL. For example:

urls.py in project

from django.conf.urls import url, include
 
urlpatterns = [
    url(r'^app01/', include('app01.urls', namespace='app01')),
    url(r'^app02/', include('app02.urls', namespace='app02')),
]

urls.py in app01

from django.conf.urls import url
from app01 import views
 
app_name = 'app01'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

urls.py in app02

from django.conf.urls import url
from app02 import views
 
app_name = 'app02'
urlpatterns = [
    url(r'^(?P<pk>\d+)/$', views.detail, name='detail')
]

Now, the URL names in my two app s are duplicate. When I reverse the URL, I can get my current URL through the namespace name.

Syntax:

'namespace name: URL name'

Use in template:

{% url 'app01:detail' pk=12 %}

Used in functions in views

v = reverse('app01:detail', kwargs={'pk':11})

In this way, even if the names of URLs in the app are the same, I can get the correct URLs by reversing them.

 

 

Posted by Fking on Sun, 27 Oct 2019 19:09:19 -0700