Implementation of django2 Note Routing path Syntax

  • 2021-07-22 10:14:30
  • OfStack

On September 23rd, Django released version 2.0 a1, which is an feature freeze version. If there is no accident, no new functions will be added to the official version 2.0. According to the past rules, it is expected that the official version will be released in December.

Note: Django 2.0 was officially released on December 2nd. (Link)

2.0 is undoubtedly a milestone release, removing support for Python 2.7, requiring a minimum of 3.4 and above, and it is recommended to use a version of 3.5 and above.

What 's new in Django 2.0 Documentation 1 lists three new features:

Simpler URL Routing Syntax (Simplified URL routing syntax)

Optimization for Mobile Devices for admin Applications (Mobile-friendly contrib. admin)

Support for SQL windowed expressions (Window expressions)

The first feature is mainly used in dynamic routing definition. The main change in the Django 2.0 code implementation is the addition of the django. urls. path function, which allows for a more concise, readable routing syntax. For example, the code of previous versions:


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

In the new version, it can also be written as:


path('articles/<int:year>/', views.year_archive),

The new syntax supports type conversion, and in the above example, the year parameter received by the year_archive function becomes an integer instead of a string.

If you have touched the Flask framework, you will find that the syntactic form and function of Variable-Rules are similar.

1 problem introduction

Here is a code snippet for Django1. X:


 from django.conf.urls import url

def year_archive(request, year):
  year = int(year) # convert str to int
  # Get articles from database

def detail_view(request, article_id):
  pass

def edit_view(request, article_id):
  pass

def delete_view(request, article_id):
  pass

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

Consider two questions:

The first problem, the year parameter in the function year_archive is of string type, so it needs to be converted to the variable value of integer type first. Of course, year=int (year) will not have an exception such as TypeError or ValueError. Is there a way, in url, that this conversion step can be automatically completed by Django?

The second question, in the three routes, article_id represents the same field in the service and uses the same regular expression, but you need to write it three times. After the article_id rule changes, you need to modify three codes at the same time. Is there a way to modify only one?

In Django 2.0, path can be used to solve the above two problems.

2 Use examples

This is a simple example:


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

Basic rules:

Use angle brackets ( < > ) Capture values from url. The capture value can contain 1 converter type (converter type), such as using the < int:name > Captures 1 integer variable. If there is no converter, it will match any string, including the/character. There is no need to add a leading slash.

The following is an example analysis table compiled according to the official 2.0 documents:

请求URL 匹配项 视图函数调用形式
/articles/2005/03/ 第3个 views.month_archive(request, year=2005, month=3)
/articles/2003/ 第1个 views.special_case_2003(request)
/articles/2003 -
/articles/2003/03/building-a-django-site/ 第4个 views.article_detail(request, year=2003, month=3, slug=”building-a-django-site”)

3 path Converter

The original document is Path converters, which is translated into converter for the time being.

Django supports the following 5 converters by default:

str, matches a non-empty string except the path separator (/), which is the default form int, matching a positive integer containing 0. slug, which matches letters, numbers, and strings composed of bars and underscores. uuid, matching formatted uuid, such as 075194d3-6885-417e-a8a8-6c931e272f00. path, which matches any non-empty string and contains the path separator

4 Custom Converter

4.1 Definitions

For 1 complex or reusable needs, you can define your own converter. A converter is a class or interface that requires three things:

regex class attribute, string type The to_python (self, value) method, where value is the string matched by the class attribute regex, returns the specific Python variable value for Django to pass into the corresponding view function. The to_url (self, value) method, in contrast to to_python, value is a concrete Python variable value that returns its string and is typically used for url reverse references.

Let's take a look at how the default IntConverter and StringConverter are implemented:


 class IntConverter:
  regex = '[0-9]+'

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

  def to_url(self, value):
    return str(value)


class StringConverter:
  regex = '[^/]+'

  def to_python(self, value):
    return value

  def to_url(self, value):
    return value

The second example is a 4-bit year converter implemented by ourselves.


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

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

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

4.2 Registration

Register it in the URL configuration using register_converter:


 from django.urls import register_converter, path

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

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

5 Using regular expressions

If the above paths and converters still do not meet the requirements, regular expressions can also be used, in which case the django. urls. re_path functions should be used.

In Python regular expressions, the named grouping syntax is (? P < name > pattern), where name is the name and pattern is the pattern to be matched.

The previous sample code can also be written as:


 from django.urls import path, re_path

from . import views

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

This code and the previous code achieve basic functions, but there are still one difference:

The code here matches more strictly, for example, year=10000 does not match here. The variables passed to the view function are of string type, which is 1 with url.

Unnamed grouping

Generally speaking, this method is not recommended, because ambiguity and even mistakes may be introduced.

6 Import change

django. urls. path can be seen as an enhanced version of django. conf. urls. url.

For convenience, its reference path has also changed. Please note that the change of urls package path is no longer a sub-package of conf. At present, like views and conf 1, it is considered as the core component of Django.

1.X 2.0 备注
- django.urls.path 新增,url的增强版
django.conf.urls.include django.urls.include 路径变更
django.conf.urls.url django.urls.re_path 异名同功能,url不会立即废弃

7 Code rewriting

Using the new path function, the code in the "problem introduction" section 1 can be rewritten as follows:


 from django.urls import path, register_converter
from django.urls.converters import SlugConverter

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

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

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

register_converter(SlugConverter, 'article_id')
register_converter(FourDigitYearConverter, 'year')

def year_archive(request, year):
  print(type(year)) # <class 'int'>
  # Get articles from database

def detail_view(request, article_id):
  pass

def edit_view(request, article_id):
  pass

def delete_view(request, article_id):
  pass

urlpatterns = [
  path('articles/<year:year>/', year_archive),
  path('article/<article_id:article_id>/detail/', detail_view),
  path('articles/<article_id:article_id>/edit/', edit_view),
  path('articles/<article_id:article_id>/delete/', delete_view),
]

8 Summary

First, the current process of routing (url) to view (View) can be summarized as four steps:

1. url matching
2. Regular capture
3. Variable type conversion
4. View invocation

Django 2.0 has one more step of variable type conversion than before.

Second, the new path syntax can solve the following scenarios:

Automatic type conversion Common regular expression

Find out more: https://www.ofstack.com/article/165591. htm


Related articles: