命名URL和URL反向解析
前言
起始樣式,HTML中的href是寫死的,不能更改,如下示例代碼:
# urls中
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^jjzz/$', views.JJzz.as_view()),
url(r'^jjzz_index/$', views.Index.as_view()),
url(r'^jjzz_visit/$', views.Visit.as_view(),name='jz'),
]
# views中
class Visit(View):
jjzz = 'jjzz on the world'
def get(self, request,**kwargs):
# return JsonResponse({'jjzz': self.jjzz})
return render(request,"jjzz_visit.html")
class Index(View):
jjzz = 'jjzz on the world'
def get(self, request,**kwargs):
# return JsonResponse({'jjzz': self.jjzz})
return render(request,"jjzz.html")
class JJzz(View):
def get(self, request):
return redirect("/jjzz_index/")
# HTML模板中
<body>
<a href="/jjzz/">歡迎來到嘰嘰喳喳的世界</a>
</body>
為了解決這種不靈活的情況,Django提供了一種可以自動更新URL而不用手動遍歷項目的源代碼來搜索並替換對應的URL。可以通過URL的匹配規則起一個名字,一個URL匹配,模式起對應一個名字。
常規URL情況下
第一步:靜態路由命名
# urls中
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^jjzz/$', views.JJzz.as_view()),
url(r'^jjzz_index/$', views.Index.as_view(),name='jjz'),
url(r'^jjzz_visit/$', views.Visit.as_view()),
]
第二步:reverse反向解析
# views中修改
# 導入reverse功能
from django.urls import reverse
或者 from django.shortcuts import reverse,兩個是同一個reverse
class JJzz(View):
def get(self, request):
return redirect(reverse('jjz'))
# 或者return redirect('jjz')
# HTML模板中
<body>
<a href="{% url "jjz" %}">歡迎來到嘰嘰喳喳的世界</a>
</body>
【總結】只要name不變,前邊的正則匹配怎么變都沒有關系
分組情況下
第一步:靜態路由命名
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^jjzz/$', views.JJzz.as_view()),
url(r'^jjzz_index/([0-9]{4})/$', views.Index.as_view(),name='jjz'),
url(r'^jjzz_visit/$', views.Visit.as_view()),
]
第二步:reverse反向解析
# views中
# 導入reverse功能
from django.urls import reverse
class JJzz(View):
def get(self, request,*args):
return redirect(reverse('jjz',args=("2019",)))
# HTML模板中
<body>
<a href="{% url "jjzz" '2019'%}">歡迎來到嘰嘰喳喳的世界</a>
</body>
# 其中
reverse('jjzz',args=("2019",) —— 》 /jjzz_index/2019/
{% url ‘jjzz’ '2019' %} —— 》 /jjzz_index/2019/
【總結】
- 利用args傳參時要用元組或者列表將參數包括起來
- 在模板中添加參數時,要用字符串的形式
命名分組情況下
第一步:靜態路由命名
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^jjzz/$', views.JJzz.as_view()),
url(r'^jjzz_index/(?P<year>[0-9]{4})/$', views.Index.as_view(),name='jjz'),
url(r'^jjzz_visit/$', views.Visit.as_view()),
]
第二步:reverse反向解析
# views中
# 導入reverse功能
from django.urls import reverse
class JJzz(View):
def get(self, request,**kwargs):
return redirect(reverse('jjz',kwargs={"year":'2019'}))
# 或者 return redirect(reverse('jjz',args=("2019",)))
# HTML文件中
<body>
<a href="{% url "jjz" year='2019' %}">歡迎來到嘰嘰喳喳的世界</a>
<a href="{% url "jjz" '2019' %}">歡迎來到嘰嘰喳喳的世界</a>
</body
# 其中
reverse('jjz',kwargs={"year":'2019'}) --》 /jjzz_index/2019/
{% url "jjz" year='2019' %} --》 /jzzz_index/2019/
命名空間模式
不同的app中使用相同的URL命名時,使用URL的命名空間模式namespace可以定義唯一反轉命名的URL。
【示例】
# 主urls中
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中
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中
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。