命名空間與路由命名
1、 命名空間namespace
在MyDjango項目中創建新的項目應用user,並且在user文件裏創建urls.py,然後配置文件settings.py的INSTALLED_APPS中添加項目應用user,使得Django在運行的時候能夠識別項目應用user。在MyDjango文件夾的urls.py中重新定義路由信息,分別指向index文件夾的urls.py和user文件夾的urls.py,代碼如下:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
# 指向內置Admin後臺系統的路由文件sites.py
path('admin/',admin.site.urls),
# 指向index的路由文件urls.py
path('',include(('index.urls','index'),namespace = 'index')),
# 指向user的路由文件urls.py
path('user/', include(('user.urls', 'user'), namespace='user')),
]
上述代碼中,新增的路由使用Django路由函數include並且指向index文件夾的urls.py和user文件夾的urls.py。在函數include裏設置了可選參數namespace,該參數是函數include特有的參數,這就是Django設置路由的命名空間。
路由函數include設有參數arg和namespace,參數arg指向項目應用App的urls.py文件,其數據格式以元組或字符串表示;可選參數namespace是路由的命名空間。
若要對路由設置參數namespace,則參數arg必須以元組格式表示,並且元組的長度必須爲2.元組的元素說明如下:
- 第一個元素爲項目應用的urls.py文件,比如(“index.urls”,“index”)的"index.urls",這是代表項目應用index的urls.py文件。
- 第二個元素可以自行命名,但不能爲空,一般情況下是以項目應用的名稱進行命名,(“index.urls”,“index”)的"index"是以項目應用index進行命名的。
如果路由設置參數namespace並且參數arg爲字符串或元組長度不足2的時候,在運行MyDjango的時候,Django就會提示錯誤信息。
接下來分析路由函數include的作用,它是將當前路由分配到某個項目應用的urls.py文件,而項目應用的urls.py文件可以設置多條路由,這種情況類似計算機上的文件夾A,並且該文件夾下包含多個子文件夾,而Django的命名空間namespace相當於對文件夾A進行命名。Django的命名空間namespace可以爲我們快速定位某個項目的urls.py,再結合路由命名name就能快速地從項目應用地urls.py找到某條路由地具體信息,這樣就能有效管理整個項目的路由列表。有關路由函數include的定義過程,可以在Python安裝目錄下找到源碼(Lib\site-packages\django\urls\conf.py)進行解讀。
2、 路由命名name
上面都使用路由函數include並且分別指向index文件夾的urls.py和user文件夾的urls.py,命名空間namespace分別爲index和user。在此基礎上,我們在index文件夾的urls.py和user文件夾的urls.py中重新定義路由,代碼如下:
# index文件夾的urls.py
from django.urls import re_path,path
from . import views
urlpatterns = [
re_path('(?P<year>[0-9]{4}.html)',views.mydate,name='mydate'),
path('',views.index,name = 'index')
]
# user文件夾的urls.py
from django.urls import path
from . import views
urlpatterns =[
path('index',views.index,name = 'index'),
path('login',views.userLogin,name = 'userLogin')
]
每個項目應用的urls.py都定義了兩條路由,每條路由都由相應的視圖函數進行處理,因此在index文件夾的views.py和user文件夾的views.py中定義視圖函數,代碼如下:
# index文件夾的views.py
from django.http import HttpResponse
from django.shortcuts import render
def mydate(request,year):
return HttpResponse(str(year))
def index(request):
return render(request,'index.html')
# user文件夾的views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("This is userIndex")
def userLogin(request):
return HttpResponse('This is userLogin')
項目應用index和user的urls.py所定義的路由都設置了參數name,這是對路由進行命名,它是路由函數path和re_path的可選參數。路由命名name的作用等同於文件夾裏的文件名。
如果路由裏使用路由函數include,就可以對該路由設置參數name,因爲路由的命名空間namespace是路由函數include的可選參數,而路由命名name是路由函數path或re_path的可選參數,兩者隸屬於不同的路由函數,因此可在同一路由裏共存。一般情況下,使用路由函數include就沒必要再對路由設置參數name,儘管設置了參數name,但實際開發中沒有實質的作用。
注: 在不同項目應用的路由命名可以重複的,這種命名是合理的。但在一個項目中,多條路由是允許使用相同的命名的,這種方式是不合理的。
在實際開發中,支持使用路由命名,因爲網站更新或防止爬蟲程序往往需要頻繁修改路由地址,倘若在視圖或其他功能模塊裏使用路由地址,當路由地址發生更新變換時,這些模塊裏所使用的路由地址也要隨之修改,這樣就不利於版本的變更和維護;相對而言,如果在這些功能模塊裏使用路由命名來生成路由地址,就能避免路由地址的更新維護問題。