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' %} #模板渲染的时候,被django解析成了这个名字对应的那个url,这个过程叫做反向解析
在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,))) #或者直接return redirect('news-year-archive',year) redirect内部会自动调用reverse来进行反向解析
如果出于某种原因决定按年归档文章发布的URL应该调整一下,那么你将只需要修改URLconf 中的内容。
在某些场景中,一个视图是通用的,所以在URL 和视图之间存在多对一的关系。对于这些情况,当反查URL 时,只有视图的名字还不够。
注意:
为了完成上面例子中的URL 反查,你将需要使用命名的URL 模式。URL 的名称使用的字符串可以包含任何你喜欢的字符。不只限制在合法的Python 名称。
当命名你的URL 模式时,请确保使用的名称不会与其它应用中名称冲突。如果你的URL 模式叫做comment
,而另外一个应用中也有一个同样的名称,当你在模板中使用这个名称的时候不能保证将插入哪个URL。
在URL 名称中加上一个前缀,比如应用的名称,将减少冲突的可能。我们建议使用myapp-comment
而不是comment
。
今日内容
1.urlconf
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^blog/$', views.blog),
url(r'^blog/[0-9]{4}/$', views.blogs),
]
2.正则表达式
^ $ [0-9] [a-zA-Z] \d \w . * + ?
3.分组和命名分组
分组
url(r'^blog/([0-9]{4})/$', views.blogs), —— 》 分组 将捕获的参数按位置传参传递给视图函数
命名分组
url(r'^blog/(?P<year>[0-9]{4})/$', views.blogs), —— 》 命名分组 将捕获的参数按关键字传参传递给视图函数
4.include
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls')),
]
app01.urls
from django.conf.urls import url
from . import views
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^blog/$', views.blog),
url(r'^blog/(?P<year>[0-9]{4})/(?P<month>\d{2})/$', views.blogs),
]
5.URL的命名和反向解析
静态路由
url(r'^blog/$', views.blog, name='blog'),
反向解析
模板
{% url 'blog' %} _> /blog/
py文件中
from django.urls import reverse
reverse('blog') _> '/blog/'
分组
url(r'^blog/([0-9]{4})/(\d{2})/$', views.blogs, name='blogs'),
反向解析
模板
{% url 'blogs' 2222 12 %}" ——》 /blog/2222/12/
py文件中
from django.urls import reverse
reverse('blogs',args=('2019','06')) ——》 /app01/blog/2019/06/
命名分组
url(r'^blog/([0-9]{4})/(\d{2})/$', views.blogs, name='blogs'),
反向解析
模板
{% url 'blogs' 2222 12 %}" ——》 /blog/2222/12/
{% url 'blogs' year=2222 month=12 %}" ——》 /blog/2222/12/
py文件中
from django.urls import reverse
reverse('blogs',args=('2019','06')) ——》 /app01/blog/2019/06/
reverse('blogs',kwargs={'year':'2019','month':'06'}) ——》 /app01/blog/2019/06/
6.namespace
urlpatterns = [
# url(r'^admin/', admin.site.urls),
url(r'^app01/', include('app01.urls', namespace='app01')),
url(r'^app02/', include('app02.urls', namespace='app02')),
]
{% url 'app01:blogs' 2222 12 %}
reverse('app01:blogs',args=('2019','06'))