Django中url命名與反轉url,應用名稱空間和例項名稱空間
url命名
為什麼需要給url命名?
因為url是經常變化的。如果在程式碼中寫死可能會經常改程式碼。給url取個名字,以後使用url的時候就使用他的名字進行反轉就可以了,就不需要寫死url了。
示例:
在專案中新建一個front的app,views.py中寫入一下程式碼:
from django.shortcuts import render
from django.http import HttpResponse
from django.shortcuts import redirect,reverse
#redirect()重定向到某個url
#reverse()反轉
# Create your views here.
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse('前臺首頁')
else:
login_url = reverse('login')#urls.py中的url的name
print(login_url)#在控制檯可檢視列印的東西
return redirect(login_url)
def login(request) :
return HttpResponse('前臺登入頁面')
意思是當用戶訪問前臺首頁時,如果沒有傳遞一個使用者名稱,那麼將跳轉至登入頁面。
front中建立一個urls.py,寫入一下程式碼
from django.urls import path
from . import views
urlpatterns = [
path('',views.index,name = 'index'),
path('login/',views.login,name = 'login'),
]
主urls.py中寫入
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('front.urls')),
]
當我們輸入
http://127.0.0.1:8000
就會自動跳轉至
http://127.0.0.1:8000/login
而當我們傳入一個使用者名稱才能跳轉至“前臺首頁”,
例如
http://127.0.0.1:8000/?username=xxx
應用(app)名稱空間
在多個app之間,有可能產生同名的url。這時候為了避免反轉url的時候產生混淆,可以使用應用名稱空間,來做區分。定義應用名稱空間非常簡單,只要在app
的urls.py
中定義一個叫做app_name
的變數,來指定這個應用的名稱空間即可。這裡我們再建立一個app名為’cms’的app,然後再views.py檔案中寫入:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse('CMS首頁')
def login(request):
return HttpResponse('CMS登入頁面')
然後新建一個urls.py檔案,寫入程式碼:
from django.urls import path
from . import views
urlpatterns = [
path('',views.index,name = 'index'),
path('login',views.login,name = 'login'),
]
然後在主urls.py檔案中新增進去cms的url:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('front.urls')),
path('cms/',include('cms.urls')),
]
然後我們輸入網址http://127.0.0.1:8000
發現跳轉至了cms登入頁面去了,而我們是想讓他跳轉至前臺登入頁面啊!
這是因為我們現在的專案中有兩個app,在這兩個app中我們都將各自的主頁url取名為‘index’,登入頁面也都是命名為’login’,在
return redirect( reverse('login') )
進行反轉的時候,Django不能準確的找到需要跳轉的頁面,所以他就會跳轉至找到的第一個’login’的頁面。這個時候我們就需要讓Django明確的知道需要跳轉的頁面,所以我們在每個app中的urls.py中新增一個變數app_name
front中的urls.py中新增:
app_name = 'front'
cms中的urls.py中新增:
app_name = 'cms'
然後我們需要明確的指出需要跳轉的頁面,在front中的views.py中的index函式修改為
def index(request):
username = request.GET.get('username')
if username:
return HttpResponse('前臺首頁')
else:
login_url = reverse('front:login')
print(login_url)
return redirect(login_url)
這樣Django就明確的知道需要跳轉至哪一個頁面了。
例項名稱空間
一個app,可以建立多個例項。即可以使用多個url對映同一個app。所以這就會產生一個問題。以後在做反轉的時候,如果使用應用名稱空間,那麼就會發生混淆。為了避免這個問題。我們可以使用例項名稱空間。例項名稱空間也是非常簡單,只要在include
函式中傳遞一個namespace
變數即可。
示例:
在主urls.py中對cms新增兩個對映,然後例項化命名
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('front.urls')),
path('cms1/',include('cms.urls',namespace='cms1')),
path('cms2/',include('cms.urls',namespace='cms2')),
]
然後我們也修改一下cms的views.py中index函式的程式碼,沒有傳入使用者名稱進來時直接跳轉至登入頁面。
from django.shortcuts import reverse,redirect
def index(request):
username = request.GET.get("username")
if username:
return HttpResponse('CMS首頁')
else:
# 獲取當前的名稱空間
current_namespace = request.resolver_match.namespace
return redirect(reverse("%s:login" % current_namespace))
這樣我們就使用cms1進入時,就會進入cms1的登入頁面,使用cms2進入,就會進入cms2的登入頁面。就不會產生混淆了。