Django-2的路由层(URLconf)

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表;你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码对应执行。

简单的路由配置

Django 2.+版本中 path路径匹配的是字符串 ,  re_path路径匹配的是正则匹配

Django1.+版本 中 url  就是2.+版本中的 re_path和path 的结合体

from django.contrib import admin
from django.urls import path,re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^$',views.index),                       # 含有正则匹配根路径
    path('shopping',views.shopping),                  # 不含正则使用path
    re_path(r'^active/(\d{4})/$',views.active),       # 正则也可以使用分组 ,匹配任意四位数字  如 active/1234/
    re_path(r'^active/(\d{4})/(\d{2})/$')             # 匹配任意年月日时间  如博客的日期   active/2016/09
]

 

注意 : 

  • 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
  • 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles
  • 每个正则表达式前面的'r' 是可选的但是建议加上。它告诉Python 这个字符串是“原始的” —— 字符串中任何字符都不应该转义

 

有名分组

上面的示例使用简单的、没有命名的正则表达式组(通过圆括号)来捕获URL 中的值并以位置 参数传递给视图。在更高级的用法中,可以使用命名的正则表达式组来捕获URL 中的值并以关键字 参数传递给视图。

在python 正则表达式中, 命名正则表达式组的语法是(?P<name>正则表达式), 其中 name 是组的名字 , 正则表达式 是要匹配的内容 , 

from django.urls import path,re_path

from app01 import views

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

这个实现与前面的示例完全相同,只有一个细微的差别:捕获的值作为关键字参数而不是位置参数传递给视图函数。例如:

#/articles/2005/03/ 请求将调用views.month_archive(request, year='2005', month='03')函数,而不是views.month_archive(request, '2005', '03')。
    #/articles/2003/03/03/ 请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。


re_path(r'^artivels/(?P<year>\d{4})/(?P<month>\d{4})/$',views.artivels)  
 # 把正则匹配分组命名 , 这个传参含有  year=1234,mouth = 02
 # 这个可以获取到匹配成功的数字,   利用获取到的数字做其他功能

 

在实际应用中,这意味你的URLconf 会更加明晰且不容易产生参数顺序问题的错误 —— 你可以在你的视图函数定义中重新安排参数的顺序。当然,这些好处是以简洁为代价;

 

分发

# 分发include
    # re_path(r'^app01/', include('app01.urls')),
    # re_path(r'^app02/', include('app02.urls')),

在每个视图应用中到创建一个属于自己的应用urls  只要匹配的属于自己的应用,就直接到自己的url中找视图函数

 

反向解析

意思  : 

1、首先给url起一个别名。例如 : re_path(r'^article/(\d{4})/$,views.year_archive, name = "xxx"')    xxx就是一个名字

2、然后在login.html中写上{%  url ‘别名’’  %}    ,如果在页面中点击查看元素,它会变成login.html,,,当然我的是分发了,,就会变成test/login.html

3、这样你就可以修改你的正则了,,因为他是按照别名走的,不会影响。

 

在使用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() 方法。

 

例子:

考虑下面的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.core.urlresolvers import reverse
from django.http import HttpResponseRedirect

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

如果出于某种原因决定按年归档文章发布的URL应该调整一下,那么你将只需要修改URLconf 中的内容。

在某些场景中,一个视图是通用的,所以在URL 和视图之间存在多对一的关系。对于这些情况,当反查URL 时,只有视图的名字还不够。

 

例子中:

分析:想我们一开始写的硬编码,也就是吧action要跳转的路径写死了。但是像淘宝,天猫等都会经常更新新东西,,那么你的页面上的url路径也会时不时的变化。但是如果有特别多的商品,那么你就得去服务端一个一个的改,这样显得很麻烦,那么有没有一种机制帮我们解决问题呢?那就按照我下面的办法解决。就把url路径写活了。

1、首先给url起一个别名。

2、然后在login.html中写上{%  url ‘别名’’  %}    ,如果在页面中点击查看元素,它会变成login.html,,,当然我的是分发了,,就会变成test/login.html

3、这样你就可以修改你的正则了,,因为他是按照别名走的,不会影响。

 

urls.py

 

 

 

 

 

 

login.html

 

 

 

 

 

 

查看元素的结果:

 

这样的好处是:无论你怎么改你要匹配的url,只要你写上了别名。在html实现了模板语法,就会去找别名对应的那个url,以后不管你怎么改url都没事,就写活了,就不像一开始写的硬编码了。

posted @ 2018-10-22 21:06  heshun  阅读(461)  评论(0编辑  收藏  举报