django必備知識點 路由
1.Django生命週期請求流程圖
- 瀏覽器>>
- 傳送請求(Http請求) >>
- web服務閘道器介面(django預設的wsgiref模組不能承受高併發,最大隻有1000左右) >>
- 中介軟體 >> 快取資料庫(返回給中介軟體已經快取過的資料) >>
- urls.py(路由層) >>
- views.py(檢視層) >>
- templates(模板層:存放html靜態檔案) models.py(模型層:存放假架接資料庫)>>
- 資料庫(返回給模型層需要的資料)
2.什麼是URL配置(URLconf)
- URL排程器 | Django 文件 | Django (djangoproject.com)
- URL配置(URLconf)就像Django 所支撐網站的目錄。
- 它的本質是URL與要為該URL呼叫的檢視函式之間的對映表。
- 你就是以這種方式告訴Django,對於這個URL呼叫這段程式碼,對於那個URL呼叫那段程式碼。
2.1 傳統路由
- 要從 URL 中取值,使用尖括號。
- 捕獲的值可以選擇性地包含轉換器型別。比如,使用
<int:nid>
來捕獲整型引數。如果不包含轉換器,則會匹配除了/
外的任何字元。 - 這裡不需要新增反斜槓,因為每個 URL 都有。比如,應該是
article
而不是/article
- 除了int,還有以下型別:
- int,整數
- str,字串 /
- slug,字母+數字+下滑線+-
- uuid,uuid格式
- path,路徑,可以包含 /
2.2 無名分組和無名分組
2.2.1 無名分組
re_path(r"^del/(\d+)/")
# 前端路由訪問 http://127.0.0.1:8000/del/1/
# 後端
def del(request,id, *args, **kwargs):
# 有一個位置引數會接收到 前端路由地址中的引數 1
print(id)
print(args) # ('1',)
print(kwargs)
return HttpResponse("del_book")
2.2.2 有名分組
# 路由語法
re_path(r"^del/(?P<year>\d+)/") # 匹配到任意資料 ---> 用 year關鍵字接收到
# 前端路由訪問 http://127.0.0.1:8000/del/1/
# 後端
def del(request,year, *args, **kwargs):
# 上面的位置引數必須跟 url 裡面的正則匹配的變數名一致
# 如果你不跟路由一樣,會報錯,提示缺少一個必要的位置引數
print(year)
print(args)
print(kwargs) # {'year': '1'}
return HttpResponse("del_book_one")
2.2.3 有名分組和無名分組混用
# 無名有名混合使用
re_path(r'^index/(\d+)/(?P<year>\d+)/', views.index),
# 前端訪問 http://127.0.0.1:8000/del_two/1/2/
# 後端只會接收到有名分組而無法接收到無名分組
# 結論就是:不能混用
2.3 請求示例
-
http://localhost:8000/article/?nid=199,django會匹配到 路徑 path('article/', views.article),拿到nid值並列印
-
http://localhost:8000/news/12/,django會匹配到 news/
<int:nid>
/ 拿到nid的值並列印 -
urls.py
from django.contrib import admin
from django.urls import path
from apps.web import views
urlpatterns = [
path('news/<int:nid>/', views.news),
path('article/', views.article),
]
- Views.py
def news(request, nid):
print(nid)
return HttpResponse("新聞")
def article(request):
nid = request.GET.get("nid")
print(nid)
return HttpResponse("文章")
3. 路由分發
由於Django專案會建立很多app,一旦多起來看這很嘈雜,然後我們就可以使用include進行路由拆分,建立多個app,統一放在apps資料夾下,每個app各自建立一個urls.py檔案
3.1 include分發
include
用於包含其他 URL 配置。這樣可以將一個大的 URL 配置拆分成多個小的配置檔案,提高可讀性和維護性。
- api/web兩個app
- api app
# api/urls.py
from django.urls import path
from apps.api import views
urlpatterns = [
# auth
path('auth/', views.auth),
# login
path('login/', views.login)
]
# api/views.py
from django.shortcuts import render, HttpResponse
def auth(request):
return HttpResponse("Hello, world. You're at the")
def login(request):
return HttpResponse("Hello, world. You're")
- web app
# web/urls.py
from django.urls import path
from apps.web import views
urlpatterns = [
# news
path('home/', views.home),
# article
path('article/', views.article)
]
# web/views.py
from django.shortcuts import render, HttpResponse
def home(request):
return HttpResponse("主頁")
def article(request):
return HttpResponse("文章")
- 根目錄 urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('api/', include('apps.api.urls')),
path('web/', include('apps.web.urls')),
]
- 根據根目錄的路徑字首,api/或者web/ 找到對應的app,從而找到相對應的路徑
3.2 手動路由分發,可以與app無關
path('user/add/', views.login),
path('user/delete/', views.login),
path('user/edit/', views.login),
path('user/list/', views.login),
path('user/', ([
path('add/', views.login),
path('delete/', views.login),#/user/delete/
path('edit/', views.login),
path('list/', views.login),
], None, None)),
純粹幫助提取功能的URL,防止重複編寫。
3.3 路由分發的本質
- url對應函式
path(api/auth/',views.api.auth)
- url對應元祖
# include返回的是個元祖
path('api/auth',include([] None None))
4. 反向解析 name,reverse
4.1 反向解析的本質
- 先給路由起一個別名,然後,透過一些方法去解析別名,可以得到這個別名對應的路由地址
- 先給路由與檢視函式起一個別名
path('auth/', views.auth, name="V1"),
4.2. 後端反向解析
from django.urls import reverse
# urls.py
urlpatterns = [
# auth
path('auth/', views.auth, name='v2'),
# login
path('login/', views.login, name="V1")
]
# views.py
def login(request):
url = reverse("v2")
return redirect(url)
4.3 前端反向解析
<a href="{% url 'v2' %}">111</a>
4.4 無名分組的反向解析
- 有名分組和無名分組的反向解析是一樣的
- 有名分組是用kwargs引數,無名用args
# 後端
reverse("路由對映的別名",args=(額外的引數,))
# 前端
<a href="{% url '路由對映的別名' 額外的引數 %}">跳轉連結</a>
5.名稱空間 namespace
- 當多個應用出現相同的別名,反向解析不會自動識別應用字首
- 正常情況下的反向解析是不能識別字首的