System.Data.SQLite.Core for .NET 5 Core manual reference
django檢視
官方對於路由分發的介紹:
https://docs.djangoproject.com/zh-hans/3.2/topics/http/urls/
一般使用
路由分發應該在urls.py中進行。預設的根urls是通過settings檔案配置的:ROOT_URLCONF = '<專案名>.urls'
。
路由的分發靠的是urlpatterns列表來的定義的,其內的元素是path
或re_path
。
如:
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/' , admin.site.urls),
]
path
的一般引數:path('admin/', admin.site.urls, name="myadmin")
admin/
是一段字串,可以直接寫成url,也可以帶上過濾器,當django自上而下匹配到這個url時,會生成一個HttpRequest物件傳給檢視的的一個引數。
admin.site.urls
是一個檢視函式,用於處理請求。
name="myadmin"
:name引數可以為dango的反向解析,動態生成url提供幫助,和app_name
使用效果更好。
關於url以"/"結尾的匹配:如path('admin/', admin.site.urls)
admin/
和admin
,但若是path('admin', admin.site.urls)
的話,就只能匹配到admin
。
路由轉發
通常,我們會在每個app裡,各自建立一個urls.py路由模組,然後從根路由出發,將app所屬的url請求,全部轉發到相應的urls.py模組中。
要實現這個功能,需要用到django.urls.include
模組。
如
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path("app1/" , include("app1.urls")),
path("app2/", include("app2.urls")),
]
之後我們就可以在app的urls中做進一步的處理了。
需要注意的是:app.urls中接收到的url是已經去掉匹配部分的。如依照上面的路由,app1/user/index
到了app1.urls中時,就剩下了user/index
,所以寫路由分發時需要注意。而且app中的urls.py需要我們手動建立。
轉換器
轉換器本質上就是一個使用正則表示式匹配url,但是它可以自動將url中匹配的內容轉換成我們需要的資料格式傳給request,也可以動態生成url。
預設情況下,Django內建下面的路徑轉換器:
- str:匹配任何非空字串,但不含斜槓/,如果你沒有專門指定轉換器,預設使用該轉換器
- int:匹配0和正整數,返回一個int型別
- slug:可理解為註釋、字尾、附屬等概念,是url拖在最後的一部分解釋性字元。該轉換器匹配任何ASCII字元以及連線符和下劃線,比如building-your-1st-django-site;
- uuid:匹配一個uuid格式的物件。為了防止衝突,規定必須使用破折號,所有字母必須小寫,例如075194d3-6885-417e-a8a8-6c931e272f00。返回一個UUID物件;
- path:匹配任何非空字串,重點是可以包含路徑分隔符’/‘。這個轉換器可以幫助你匹配整個url而不是一段一段的url字串。要區分path轉換器和path()方法
使用方式
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
'articles/<int:year>/'
中的int是轉換器,而year是request中的引數名。
自定義轉換器
預設的轉換可以實現一般的匹配,但是假如要匹配複雜度和自定義程度比較高的url時,可以自定義一個轉換器。
第一步:自定義類
在app中建立一個converters.py
,用於放置轉換器類
關鍵實現:
- 類屬性:regex
這裡需要寫正則表示式 - 類方法:to_python
轉換資料給檢視用,失敗要丟擲ValueError異常 - 類方法:to_url
返回url供反轉操作,失敗要ValueError異常
# app/converters.py
class Year:
regex = "\d{4}"
def to_python(self, value):
try:
return int(value)
except ValueError:
raise ValueError
def to_url(self, value):
return value
第二步:在url中註冊
# polls/urls.py
from django.urls import path, register_converter
from . import views, converters
app_name = "polls" # app_name的作用後面講述
# 註冊轉換器為year_conv
register_converter(converters.Year, "year_conv")
urlpatterns = [
path("", views.index, name="index"),
# 和預設轉換器一樣使用自定義轉換器
path("<year_conv:year>/", views.test, name="test"),
]
關於re_path
Django2.0的urlconf雖然改‘配置方式’了,但它依然向老版本相容。而這個相容的辦法,就是用re_path()
方法。re_path()
方法在骨子裡,根本就是以前的url()
方法,只不過匯入的位置變了。下面是一個例子,對比一下Django1.11時代的語法,有什麼太大的差別?
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]
與path()
方法的不同點:
捕獲URL中的引數使用的是正則捕獲,語法是 (?P<name>pattern)
,其中 name 是組名,pattern 是要匹配的模式。
傳遞給檢視的所有引數都是字串型別。而不像path()方法中可以指定轉換成某種型別。在檢視中接收引數時一定要小心。
反向解析及應用名稱空間
反向解析的功能可以動態生成url,防止我們將url寫死,減少維護複雜度。
反向解析可以在python程式碼中應用,也可以在django的template中應用。
如在urls中這樣定義:
from django.urls import path
from .views import index, article
urlpatterns = [
path("index/", index, name="index"),
path("article/<int:article_id>", article, name="article")
]
-
python程式碼中反向解析:
# 1. 匯入django.urls.reverse函式 # 2. 根據urls中path物件的name引數,確定你要生成的是那個url # 3. 假如url中需要引數的話,以args或kwargs傳入 from django.http import HttpResponse from django.urls import reverse # Create your views here. def index(request): index_url = reverse("index") return HttpResponse(index_url) def article(request, article_id): # article_url = reverse("article", args=(article_id, )) article_url = reverse("article", kwargs={"article_id": article_id}) return HttpResponse(article_url)
-
在template中反向解析:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% url "index" %} {% url "article" "1234" %} </body> </html>
使用的是django模板引擎的url標籤,使用template時,應該要在settings中的
INSTALLED_APPS
新增上自己的app。
以上只利用path的name引數生成url的做法,在多個app時(如app1:name="index", app2:name="index")可能就不怎麼適用了。
因此django為我們提供了一個app_name變數,可以為我們標識不同的app。
在app/urls.py中我們可以自定義一個獨一無二的app_name,如:
from django.urls import path
from .views import index, article
app_name = "app01"
urlpatterns = [
path("index/", index, name="index"),
path("article/<int:article_id>", article, name="article")
]
在使用的時候只需要在name字元前面加上app_name:
即可,如:
article_url = reverse("app01:article", kwargs={"article_id": article_id})
template的使用也是如此,改變第一個引數即可。
django還可以為不同的物件提供標識,實現方式時:給include新增name_space引數。具體可點選:關於include和name_space的使用。