因为url是经常变化的。如果在代码中写死可能会经常改代码。给url取个名字,以后使用url的时候就使用他的名字进行反转就可以了,就不需要写死url了。
首先我们需要在path
函数中传递一个name
参数,即给url命名,示例代码如下:
urlpatterns = [
path('',views.index,name='index'),
path('login/',views.login,name='login')
]
然后我们就可以在 views.py 文件中使用reverse函数来获取指定name
对应的url,示例代码如下:
from django.http import HttpResponse
from django.shortcuts import redirect, reverse
def index(request):
username = request.GET.get('username')
if username is None:
re_url = reverse('login')
# re_url的值即为 login/
return redirect(re_url)
else:
text = '前台首页'
return HttpResponse(text)
def login(request):
text = '前台登陆首页'
return HttpResponse(text)
虽然使用name
来给url命名很方便,但是在多个app之间,很有可能会存在name
属性相同的url,比如front和cms中都含有name
叫做login的url,为了避免反转url时产生混淆,可以使用应用命名空间来区分。
定义应用命名空间的方法是:在app
的urls.py
中定义一个app_name
的变量,用来指定这个应用的命名空间。示例代码如下:
front/urls.py
from django.urls import path
from . import views
# 在这里添加app_name变量
app_name = 'front'
urlpatterns = [
path('', views.index, name='index'),
path('login/', views.login, name='login'),
]
front/views.py
from django.shortcuts import redirect, reverse
def index(request):
username = request.GET.get('username')
if username is None:
# 使用reverse(app_name:url_name)的形式
re_url = reverse('front:login')
return redirect(re_url)
else:
text = '前台首页'
return HttpResponse(text)
def login(request):
text = '前台登陆首页'
return HttpResponse(text)
在开发过程中,我们可能会遇到想要让不同的urls映射同一个app,但是如果这样做的话,在进行反转的时候,应用命名空间就会出现混淆,如下所示:
[projectname]/urls.py
urlpatterns = [
path('',include('front.urls')),
path('cms1/',include('cms.urls')),
path('cms2/',include('cms.urls')),
]
cms/urls.py
from django.urls import path
from . import views
app_name = 'cms'
urlpatterns = [
path('',views.index,name='index'),
path('login/',views.login,name='login')
]
cms/views.py
def index(request):
username = request.GET.get("username")
if username:
return HttpResponse('CMS首页')
else:
re_url = reverse(cms:login)
return redirect(re_url)
def login(request):
return HttpResponse("CMS登录页面")
在上述这种情况下,由reverse
获取的url到底是cms1/login
还是cms2/login
呢,这就会造成混淆。因此引入实例命名空间,需要在include
函数中指定namespace
参数,示例代码如下:
[projectname]/urls.py
urlpatterns = [
path('',include('front.urls')),
path('cms1/',include('cms.urls',namespace='cms1')),
path('cms2/',include('cms.urls',namespace='cms2')),
]
cms/views.py
def index(request):
username = request.GET.get("username")
if username:
return HttpResponse('CMS首页')
else:
# 使用request.resolver_match.namespace获取实例命名空间
current_namespace = request.resolver_match.namespace
re_url = reverse("%s:login" % current_namespace)
return redirect(re_url)
def login(request):
return HttpResponse("CMS登录页面")
使用上述的代码,就可以从cms1/
转跳到cms1/login
从cms2/
转跳到cms2/login
,避免了混淆。