Django之URL分發器
URL對映:
檢視寫完後,要與URL進行對映(即使用者在瀏覽器中輸入什麼樣的url可以請求到這個檢視函式),Django會從url.py檔案中尋找相對應的檢視,這個檔案中有個urlpatterns變數,這個變數中通過path函式包含著要請求的檢視。為什麼會從url.py檔案中尋找呢,因為在setting中有個ROOT_URLCONF = 'gjz.urls';所有的URL對映都是從這個專案的url檔案中開始。
view.py檔案:
from django.http import HttpResponse def index(request): return HttpResponse("ok")
專案的url.py檔案:
from django.contrib import admin from django.urls import path,include from front import views urlpatterns = [ path('admin/', admin.site.urls), path("index/",views.index), ]
當我們在瀏覽器中輸入127.0.0.1:8000/index的時候Django會從url.py檔案中尋找path函式包含的匹配規則中的index/,並對映到對應的檢視。
URL的模組化:一個Django專案是由多個app組成的,如果把每個APP的url對映都放到專案的url檔案中顯得太多了,不好管理,最好的辦法就是把每個APP的對映條件放到自己的APP內,即在自己的APP內新增一個url檔案,這個url檔案中包含著自己app的對映關係,即url的模組化。
比如有兩個APP一個Front,一個CMS模組那麼該如何對映呢:
1APP中新增url.py檔案
2專案的url.py檔案中包含每個app的url.py檔案,專案url.py程式碼如下:
from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path("front/",include("front.urls")), path("cms",include("cms.urls")), ]
3每個APP的url.py程式碼:
Front中的url.py
from django.urls import path from . import views urlpatterns=[ path("",views.index), ]
cms的url.py
from django.urls import path from . import views app_name = "cms" urlpatterns = [ path("",views.index), ]
當我們在瀏覽器中輸入127.0.0.1:8000/front的時候,Django會從專案的url檔案中開始找,找到後再去include包含的url中接著找,然後在返回對應的檢視。
path()函式與repath()函式:
path()函式與repath()函式最大的區別就是repath()第一個引數route可以使用正則表示式來實現一些複製的需求。
path()定義為:path(route,view,name=None,kwargs=None);前兩個引數是必須的後面兩個可以省略
route引數:url的匹配規則。可以傳遞引數以<>尖括號的形式傳遞,並且可以指定引數的型別:
<int:id>:匹配熱議的零或者正整數
<str:id>:非空的字串型別
<uuid>:匹配uuid字串
<path>:非空英文字串,可以包含斜槓
view引數:檢視函式或者類檢視函式或者include()函式的返回值
name引數:這個URL的名字
kwargs引數:可以給檢視傳遞一些額外的引數,這個引數是一個字典型別
include()函式:
包含一個APP的url.py檔案或者包含一個列表(元組),這個列表(元組)中是path函式(repath())
from django.contrib import admin from django.urls import path,include from cms import views urlpatterns = [ path('admin/', admin.site.urls), path("front/",include("front.urls")), #包含的是一個url檔案 path("cms",include([ #包含的是一個path列表 path("", views.index), path("book", views.login) ])), ]
URL中新增引數:
1預設引數:直接在檢視中新增一個引數
from django.http import HttpResponse books=[ "三國演義", "水滸傳", "西遊記", "紅樓夢" ] def index(request): return HttpResponse("ok") def book(request,id=1): #不帶引數直接訪問book則返回 “水滸傳” return HttpResponse(books[id])
2查詢字串引數:
def index(request): ID = request.GET.get("id") return HttpResponse(ID)
瀏覽器中輸入:127.0.0.1:8000/front/?id=3;
則返回數字3
查詢字串通過request.GRT.get("字串名字”)獲取;瀏覽器通過?id=123(?字串=值)
3傳遞引數:
(1)path()函式傳遞引數:path("book/<int:id>"),檢視中必須接受這個引數:def index(request,id)
(2) repath()函式傳遞引數:repath(r"book/(<int:id>)");檢視中必須接受這個引數:def index(request,id)
reverse()函式:在我們實際開發過程中url的名字可能會變動比如登入一開始用login後來變為signin,那麼我們在其他地方可能會用到這個名字,這裡一旦改變其他的地方也要改變很麻煩,這個時候就會用到name屬性給這個url取個別名,然後再反轉reverse()得到。
url.py
from django.urls import path from . import views urlpatterns=[ path("index",views.index,name="index"), # path("book/<int:id>",views.book,name="book"), #一開始url的名字是book,後來變為book_list了也不會妨礙重定向 path("book_list/<int:id>",views.book,name="book"), #name=book,給這url去個別名,可以通過這個別名來找到這個url ]
views.py
from django.http import HttpResponse from django.shortcuts import redirect,reverse books=[ "三國演義", "水滸傳", "西遊記", "紅樓夢" ] def index(request): return redirect(reverse("book",kwargs={"id":3})) #帶關鍵字的反轉 def book(request,id=1): return HttpResponse(books[id])
應用名稱空間與例項名稱空間:
應用名稱空間:是給這個app取個名字;作用:每個APP可能會有相同url的名字,比如前臺和後臺都有登入的介面login,那麼當我們輸入login是去前臺的介面呢還是後臺的介面呢?這個時候就需要指定app的名字了。
from django.urls import path from . import views app_name = "cms" #給這個APP取個名字叫做cms urlpatterns = [ path("",views.index), path("login/",views.login), path("book<int:id>/",views.book), ]
from django.http import HttpResponse from django.shortcuts import redirect,reverse books=[ "三國演義", "水滸傳", "西遊記", "紅樓夢" ] def index(request): return redirect(reverse("cms:book",kwargs={"id":3})) #當我們要跳轉到cms中的book介面的時候用cms:book方式
例項名稱空間:一個app可以建立多個例項,即多個url對映同一個app,這樣在做反轉的時候容易混亂。這個時候就需要例項名稱空間了,只需要在include函式中傳遞一個namespace變數即可。
""" from django.contrib import admin from django.urls import path,include from cms import views urlpatterns = [ path("front1/",include("front.urls",namespace="front1")), path("front2/",include("front.urls",namespace="front2"),), #front1和front2同時對映到了front.urls模組,為了區分他們使用例項名稱空間 ]
views.py
from django.http import HttpResponse from django.shortcuts import redirect,reverse def index(request): current_app = request.resolver_match.namespace #獲取當前例項名稱空間的名字 return redirect(reverse("%s:book" %current_app,kwargs={"id":2})) #使用這個url來找到book def book(request,id): return HttpResponse("book")
自定義URL轉換器: