1. 程式人生 > >Django之URL分發器

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轉換器: