繼 Day23 的一些命名空間的介紹,才讓我有機會進入命名空間這一個坑,官網上所介紹的命名空間其實要來的複雜許多
原本想要在 Day23 再額外介紹 更深入的命名空間,但是我發現內容多到可以直接上一篇新的xD
Day23 介紹的只是一個最直觀且易懂的方法
今天的主題原本不在計畫中,我原本不打算用這一招的
但是頭都栽下去了,在找資料的過程中發現這一個議題,並沒有看到中文網站在介紹這個 (或許是我關鍵字下的太差...
還是有拉,但是我還是不懂,
感覺像是在看照文本翻譯的教學
所以今天的主題著重在 深入探討 命名空間 !
再次強調,官網講得很清楚,不過範例給得太少且用字晦澀,如果你是第一看的人,很難能夠領悟
轉換 命名空間
這邊我會附上官網的教學,你可以做對照,相信你能更容易領悟!
在開始之前,先帶大家了解命名空間 其實分成兩種,我們可以分別把它們想成 本名及綽號
這裡要先強調一個觀念,實例命名空間必須唯一,想想看,一個人會有很多個綽號,但是你不可能幫別人取兩次相同的綽號,對吧 ^^
接著我會透過 Day23的範例替大家說明 命名空間搜尋的規則
# top-level urls.py
from django.contrib import admin
from django.urls import path, include
from .views import test
urlpatterns = [
path('admin/', admin.site.urls),
# vendors app 有兩個綽號 f-vendors 及 s-vendors
path('welcome/', include('vendor.urls', namespace='f-vendors')),
path('vendor/', include('vendor.urls', namespace='s-vendors')),
path('test/', test, name='index'),
]
# vendor/urls.py
from django.contrib import admin
from django.urls import path
from . import views
app_name = 'vendors'
urlpatterns = [
path('', views.showtemplate, name='index'),
path('<int:id>/', views.singleVendor, name='vendor_id'),
path('create', views.vendor_create_view, name='create'),
path('fcreate', views.food_create_view, ),
]
因為版面關係,這裡用 App Namespcae 代表 Application Namespace
假如我們要搜尋的是 vendors:index
,這它的搜尋規則是
app_name
,如果存在,則接下來找底下的特徵(就是path() 每一個定義的 name),而此時 app_name
的特徵有 index、vendor_id、createindex
,它所 反轉 (reverse) 的網址便是對應到前方的'',因此網址便是 vendor/
預設應用命名空間
s-vendors
應用命名空間
,則會直接去找綽號 - 實例命名空間
接下來直接帶大家看範例!
因為第1步及第2步已經帶大家了解過了,所以我們直接說明 3~5
我創建一個 test.html 來帶大家了解,可以搭配著 urls.py 來看
# top-level urls.py
from django.contrib import admin
from django.urls import path, include
from .views import test
urlpatterns = [
...略
# vendors app 有兩個綽號 f-vendors 及 s-vendors
path('welcome/', include('vendor.urls', namespace='f-vendors')),
path('vendor/', include('vendor.urls', namespace='s-vendors')),
path('test/', test, name='index'),
]
<p> vendors:index :</p> {% url 'vendors:index' %}<br/>
因為此時我的 {% url 'vendors:index' %}
不是建立在 app_name - vendors底下,所以找不到符合的應用命名空間(3),所以會用最後一個被綁定的實例空間 - s-vendor
此時我們的網頁上就會秀出 /vendor/
而當你調皮搗蛋 交換了綽號的位置
urlpatterns = [
...略
# 互換位置
path('vendor/', include('vendor.urls', namespace='s-vendors')),
path('welcome/', include('vendor.urls', namespace='f-vendors')),
path('test/', test, name='index'),
]
此時我們的網頁上就會秀出 /welcome/
也就是說! 因為找不到 預設的應用命名空間
,所以它就用最後一個被綁定的!
但此時如果你又將 test.html
改成這樣
urlpatterns = [
...略
# 出現了 預設應用命名空間
path('vendor/', include('vendor.urls', namespace='vendors')),
path('welcome/', include('vendor.urls', namespace='f-vendors')),
path('test/', test, name='index'),
]
我們網頁就會重新秀出 /vendor/
,因為 預設應用命名空間
出現了,所以它就先採納 預設應用命名空間
,而不是 最後一個被綁定的!
最後,我們將 test.html
修改成這樣
<p>s-vendors:index :</p> {% url 's-vendors:index' %}<br/>
<p>f-vendors:index :</p> {% url 'f-vendors:index' %}<br/>
此時我們的網頁上就會秀出
因為 應用命名空間
找不到,所以就改用 實例命名空間
去找囉!
那又如果說... 你不替 實例命名空間 取綽號
urlpatterns = [
...略
#不定義 綽號 - 實例命名空間,則主動被授予 應用命名空間
path('vendor/', include('vendor.urls')),
path('welcome/', include('vendor.urls')),
path('test/', test, name='index'),
]
那麼 Django 會自動將自己的 應用命名空間
給它們當 實例命名空間
,但是 Django 會警告你不要這麼做! 因為此時這兩個傢伙 使用相同的綽號 - vendors
WARNINGS:
?: (urls.W005) URL namespace 'vendors' isn't unique. You may not be able to reverse all >URLs in this namespace
所以此時大家都擁有 預設應用命名空間,而我們的規則是,誰有 預設命名空間,誰就會被使用
<p> vendors:index :</p> {% url 'vendors:index' %}<br/>
呼,此時的你問了 : 這樣的命名有什麼幫助? 就拿官網的投票網站來做說明吧!
它可以應用在區別 使用者 及 管理者,也就是說 投票系統都做在一起,但是透過不同的身分(也就是不同的權限!)去瀏覽相同的網頁,而不用說要為不同身分去作兩個投票系統 ^^"
今天我們深入探討了命名空間,主要覺得這議題也蠻重要的,雖然遠遠不及單純的使用 app_name:xxxxx
來的直觀,不過多學點總不是壞事 ^^,希望這對你有幫助!
如果這篇 命名空間 的介紹有誤的,歡迎各方好手指點,感恩~
From BY