This article brings you a detailed explanation (code example) of the routing system in Django. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Django’s routing system
URL configuration (URL.conf) is like the directory of the website supported by Django. Its essence is the URL and the functions to be called for the URL. Mapping table between view functions.
This is how we tell Django which function to execute when encountering which URL.
URLconf configuration
Basic format:
from django.conf.urls import url urlpatterns = { url(正则表达式,views视图,参数,别名), }
Example:
from django.conf.urls import from . import views urlparterns = { 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_detall), }
Parameter description:
Regular expression: a regular expression string
viewsView: a callable object, usually a view function
Parameters : Optional default parameters (dictionary form) to be passed to the view function
Alias: An optional name parameter
Note:
The routing system in Django version 2.0 is written as follows: (official document):
from django.urls import path,re_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), ]
The re_path of version 2.0 is used the same as the url of version 1.11.
Detailed explanation of regular expressions
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'^article/([0-9]{4})/([0-9]{2})/$',views.month_archive), url(r'^article/([0-9]{4})/([0-9]{2})/([0-9]+)',views.article_detail), ]
Notes:
1. The elements in urlpatterns match the regular expressions one by one from top to bottom in the writing order. Once the match is successful, it will not continue.
2. If To capture a value from a URL, just place a pair of parentheses around it (grouping match).
3. There is no need to add a leading backslash 2 as every URL has one, e.g. , it should be ^articles instead of ^/articles.
4. The 'r' in front of each regular expression is optional but it is recommended to add.
Supplementary instructions:
# Whether to enable the configuration item APPEND_SLASH=True that does not jump to the path with / after the URL access address. # Its function is to add '/' at the end of the URL.Other The effect is:
We defined urls.py:
from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^blog/$',views.blog) ]
When accessing http://www.example.com/blog, the default Automatically convert the URL to http://www.example/com/blog/.
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.
Group Named matching
The above example uses a simple regular expression grouped match (via parentheses) to capture values in the URL and pass them to the view as positional parameters.
In more advanced usage In , you can use grouped named matching regular expression groups to capture values in the URL and pass them to the view as keyword arguments.
In Python's regular expressions, the syntax for grouped named regular expressions is (?P
The following is a rewrite 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 one subtle difference : The captured value is passed to the view function as a keyword argument rather than a positional argument.
For example, calling the view function for the URL /articles/2017/12/ is equivalent to calling the view function in the following way:
views.month_archive(request, year="2017", month="12")
In actual applications, Using grouped naming matching can make your URLconf clearer and less prone to parameter order errors, but some developers think the grouped naming group syntax is too ugly and cumbersome.
As for which one you should use, you can decide according to your own preferences.
URLconf matching positions
URLconf looks for the requested URL, treating it as an ordinary Python string. Excludes GET and POST parameters and domain names.
For example, in a request for http://www.example.com/myapp/, the URLconf will look for /myapp/
at http://www.example.com/myapp/?page =3 request, the URLconf will still look for /myapp/
URLconf does not check the requested method. In other words, all request methods - POST, GET, HEAD, etc. for the same URL - will be routed to the same function.
The captured parameters are always strings
Every parameter captured in the URLconf is passed to the view as an ordinary Python string, regardless of the matching method used by the regular expression . For example, in the following line of 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.
Specified default values in view functions
# urls.py中 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), ]# views.py中,可以为num指定默认值def page(request, num="1"): pass
In the above example, both URL patterns point to the same view - views.page - But the first pattern doesn't capture anything from the URL.
If the first pattern matches, the page() function will use its default parameter num="1". If the second pattern matches, page() will use the num value captured by the regular expression. .
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')), # 可以包含其他的URLconfs文件 ]
Pass additional parameters to view functions (understand)
URLconfs has a hook that lets you pass a Python dictionary as an extra argument to the view function.
django.conf.urls.url() 可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。
例如:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}), ]
在这个例子中,对于/blog/2005/请求,Django 将调用views.year_archive(request, year='2005', foo='bar')。
当传递额外参数的字典中的参数和URL中捕获值的命名关键字参数同名时,函数调用时将使用的是字典中的参数,而不是URL中捕获的参数。
命名URL和URL反向解析
在使用Django 项目时,一个常见的需求是获得URL的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等)。
人们强烈希望不要硬编码这些URL(费力、不可扩展且容易产生错误)或者设计一种与URLconf 毫不相关的专门的URL 生成机制,因为这样容易导致一定程度上产生过期的URL。
换句话讲,需要的是一个DRY 机制。除了其它有点,它还允许设计的URL 可以自动更新而不用遍历项目的源代码来搜索并替换过期的URL。
获取一个URL 最开始想到的信息是处理它视图的标识(例如名字),查找正确的URL 的其它必要的信息有视图参数的类型(位置参数、关键字参数)和值。
Django 提供一个办法是让URL 映射是URL 设计唯一的地方。你填充你的URLconf,然后可以双向使用它:
根据用户/浏览器发起的URL 请求,它调用正确的Django 视图,并从URL 中提取它的参数需要的值。
根据Django 视图的标识和将要传递给它的参数的值,获取与之关联的URL。
第一种方式是我们在前面的章节中一直讨论的用法。第二种方式叫做反向解析URL、反向URL 匹配、反向URL 查询或者简单的URL 反查。
在需要URL 的地方,对于不同层级,Django 提供不同的工具用于URL 反查:
在模板中:使用url模板标签。
在Python 代码中:使用django.core.urlresolvers.reverse() 函数。
在更高层的与处理Django 模型实例相关的代码中:使用get_absolute_url() 方法。
上面说了一大堆,你可能并没有看懂。(那是官方文档的生硬翻译)。
咱们简单来说就是可以给我们的URL匹配规则起个名字,一个URL匹配模式起一个名字。
这样我们以后就不需要写死URL代码了,只需要通过名字来调用当前的URL。
举个简单的例子:
url(r'^home', views.home, name='home'), # 给我的url匹配模式起名为 home url(r'^index/(\d*)', views.index, name='index'), # 给我的url匹配模式起名为index
这样:
在模板里面可以这样引用:
{% url 'home' %}
在views函数中可以这样引用:
from django.urls import reverse reverse("index", args=("2018", ))
例子:
考虑下面的URLconf:
from django.conf.urls import url from . import views urlpatterns = [ # ... url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'), # ... ]
根据这里的设计,某一年nnnn对应的归档的URL是/articles/nnnn/。
你可以在模板的代码中使用下面的方法获得它们:
<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>
在Python 代码中,这样使用:
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,)))
如果出于某种原因决定按年归档文章发布的URL应该调整一下,那么你将只需要修改URLconf 中的内容。
在某些场景中,一个视图是通用的,所以在URL 和视图之间存在多对一的关系。对于这些情况,当反查URL 时,只有视图的名字还不够。
注意:
为了完成上面例子中的URL 反查,你将需要使用命名的URL 模式。URL 的名称使用的字符串可以包含任何你喜欢的字符。不只限制在合法的Python 名称。
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。如果你的URL 模式叫做comment,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。
在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用myapp-comment 而不是comment。
命名空间模式
即使不同的APP使用相同的URL名称,URL的命名空间模式也可以让你唯一反转命名的URL。
举个例子:
project中的urls.py
from django.conf.urls import url, include urlpatterns = [ url(r'^app01/', include('app01.urls', namespace='app01')), url(r'^app02/', include('app02.urls', namespace='app02')), ]
app01中的urls.py
from django.conf.urls import url from app01 import views app_name = 'app01'urlpatterns = [ url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]
app02中的urls.py
from django.conf.urls import url from app02 import views app_name = 'app02'urlpatterns = [ url(r'^(?P<pk>\d+)/$', views.detail, name='detail') ]
现在,我的两个app中 url名称重复了,我反转URL的时候就可以通过命名空间的名称得到我当前的URL。
语法:
'命名空间名称:URL名称'
模板中使用:
{% url 'app01:detail' pk=12 pp=99 %}
views中的函数中使用
v = reverse('app01:detail', kwargs={'pk':11})
这样即使app中URL的命名相同,我也可以反转得到正确的URL了。
以上就是本篇文章的全部内容,关于python更多精彩内容大家可以关注php中文网的Python视频教程和python文章教程栏目!!!
The above is the detailed content of Detailed explanation of routing system in Django (code example). For more information, please follow other related articles on the PHP Chinese website!