url命名/应用命名空间/实例命名空间

为什么要给url命名?

因为url是经常变化的。如果在代码中写死可能会经常改代码。给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时产生混淆,可以使用应用命名空间来区分。
定义应用命名空间的方法是:在appurls.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/logincms2/转跳到cms2/login,避免了混淆。

你可能感兴趣的:(Django)