Django之路由控制配置
路由控制配置
簡單的路由配置
Django即支援1.x版本的路由配置也支援2.x的路由配置
- 1.x版本的路由配置是使用re進行路由配置(re_path)
- 2.x版本的路由配置使用(path)進行路由配置
from django.contrib import admin from django.urls import path,re_path from app1 import views urlpatterns = [ path('admin/', admin.site.urls), path('timer/', views.timer), path('login/', views.login), #year_archive(request,year) re_path(r'^articles/([0-9]{4})/$',views.year_archive),# 匹配成功之後會將匹配成功的內容傳入到year_archive函式中,在views定義函式時要接收兩個引數 re_path(r'^articles/([0-9]{4})/([0-9]{2})/$',views.month_archive) ]
注意:
- 若要從URL 中捕獲一個值,只需要在它兩頭放置一對圓括號(捕獲的值傳遞到檢視函式中,在定義檢視函式的時候也要接收相對應傳入的引數)
- 不需要新增一個前導的反斜槓,每個URL都有(自動新增)
- 每個正則表示式前面的'r'是可選的但是簡易加上,它告訴python這個字串是“原始的” -- 字串中任何字串都不應該轉義
請求的例子:
http://127.0.0.1:8000/articles/9999/20/ #走的是month_archive
http://127.0.0.1:8000/articles/9999/ # 走的是year_archive
# url有覆蓋效果,以最先匹配的為準
路由控制之有名分組
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive)
- 使用?P<組名>給正則表示式命名,這樣就不需要考慮檢視函式中的位置引數位置錯亂了(固定寫法),並且在檢視函式中的形參命名必須以分組名字命名(關鍵字傳參)
路由控制之分發
在具體的app中建立urls.py檔案,該應用中的url全部寫在應用中的urls.py中,然後使用全域性urls去控制分發url,完成每個應用之間url解耦合
全域性中的urls.py
from django.contrib import admin from django.urls import path,re_path,include from app1 import views urlpatterns = [ path('admin/', admin.site.urls), path('timer/', views.timer), path('login/', views.login), #^也可以寫具體應用名,只是訪問時也需要加上應用名,以^開頭說明不用去匹配前面的,直接噗呸include中的內容 re_path(r"^",include("app1.urls")) ]
應用中的urls.py
from django.contrib import admin
from django.urls import path,re_path,include
from app1 import views
urlpatterns = [
re_path(r'^articles/([0-9]{4})/$',views.year_archive),# 匹配成功之後會將匹配成功的內容傳入到year_archive函式中,在views定義函式時要接收兩個引數
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive)
]
路由控制之反向解析
在使用Django 專案時,一個常見的需求是獲得URL 的最終形式,以用於嵌入到生成的內容中(檢視中和顯示給使用者的URL等)或者用於處理伺服器端的導航(重定向等)。人們強烈希望不要硬編碼這些URL(費力、不可擴充套件且容易產生錯誤)或者設計一種與URLconf 毫不相關的專門的URL 生成機制,因為這樣容易導致一定程度上產生過期的URL
- 在模版中進行反向解析
在urls.py中
# 給url命名(別名)
path('login.html/', views.login,name='log'),
在login.html中:
<!--不管url怎麼變化,這裡的action是動態去獲取名字為log的url-->
<form action="{% url 'log' %}" method="post">
<label for="username">使用者名稱
<input type="text" id="username" name="user" placeholder="請輸入使用者名稱">
</label>
<label for="pwd">密碼
<input type="password" id="pwd" name="pwd" placeholder="請輸入密碼">
</label>
<input type="submit">
</form>
- 在python views.py中進行反向解析
如果url中有正則表示式,需要在reverse函式中傳入一個args引數,並且引數的值必須符合url中的正則表示式,如果不進行替換會報錯
re_path(r'^articles/([0-9]{4})/$',views.year_archive,name='y_a')
def year_archive(request,year):
# 使用django.urls模組下的reverse模組進行反向解析
from django.urls import reverse
url = reverse('y_a',args=(year,))
print(url) #/app1/articles/2000/
# HttpResponse返回的引數時一哥字串
return HttpResponse("<h1>%s</h1>url:%s"%(year,url))
路由控制之名稱空間
名稱空間(英語:Namespace)是表示識別符號的可見範圍。一個識別符號可在多個名稱空間中定義,它在不同名稱空間中的含義是互不相干的。這樣,在一個新的名稱空間中可定義任何識別符號,它們不會與任何已有的識別符號發生衝突,因為已有的定義都處於其它名稱空間中。 由於name沒有作用域,Django在反解URL時,會在專案全域性順序搜尋,當查詢到第一個name指定URL時,立即返回 我們在開發專案時,會經常使用name屬性反解出URL,當不小心在不同的app的urls中定義相同的name時,可能會導致URL反解錯誤,為了避免這種事情發生,引入了名稱空間。
project的urls.py:
urlpatterns = [ re_path(r'^app1/', include(("app1.urls","app1"))), re_path(r'^app2/', include(("app2.urls","app2"))) ]
app1.urls.py
urlpatterns = [
re_path(r'^index/', index,name="index"),
]
app2.urls.py
urlpatterns = [
re_path(r'^index/', index,name="index"),
]
app11.views
from django.core.urlresolvers import reverse
def index(request):
return HttpResponse(reverse("app01:index"))
app02.views
from django.core.urlresolvers import reverse
def index(request):
return HttpResponse(reverse("app02:index"))