urls路由
上一節(jié)用到了urls,這里用盡量簡(jiǎn)單的語(yǔ)言講一下。網(wǎng)址url相當(dāng)于一個(gè)地址频敛,用這個(gè)去找某個(gè)公司里的某個(gè)人。
這是一個(gè)工程目錄斟赚,里面有兩個(gè)應(yīng)用,相當(dāng)于一個(gè)大院里面有兩家公司差油,那么工程目錄下的urls就相當(dāng)于大院的傳達(dá)室拗军,拿著地址找人必須先問(wèn)傳達(dá)室。
helapp這個(gè)公司比較大发侵,所以設(shè)立的一個(gè)前臺(tái)接待,只要是來(lái)傳達(dá)室找helapp這個(gè)公司的妆偏,直接領(lǐng)到這個(gè)前臺(tái)去問(wèn)接下來(lái)的路刃鳄。
daka這個(gè)公司比較小,沒(méi)有自己的前臺(tái)钱骂,那么就由大院傳達(dá)室直接領(lǐng)去辦公室(views)并且找到里面該找的人(方法)叔锐。
要從大院傳達(dá)室領(lǐng)到公司前臺(tái),就用include()方法见秽,領(lǐng)到下一級(jí)路由urls愉烙,并把匹配剩下的url傳過(guò)去。比如上圖中匹配完了‘hello’解取,交給下一級(jí)路由時(shí)‘hello’和其前面的url就都不管了步责,下一級(jí)url只處理url后面剩下的部分。
公司內(nèi)的前臺(tái)接待會(huì)根據(jù)地址找到對(duì)應(yīng)的人,應(yīng)用內(nèi)的urls會(huì)根據(jù)url找到對(duì)應(yīng)的方法蔓肯。公司前臺(tái)找人遂鹊,跟傳達(dá)室?guī)蜎](méi)有前臺(tái)的公司找人,方式是類似的省核。
如果我們想在url里寫一些動(dòng)態(tài)的變量信息傳遞給后端稿辙,Django是不喜歡用GET方法的url參數(shù)的,通常Django使用正則表達(dá)式來(lái)解析url气忠,提取出其中的變量并傳遞給方法。
簡(jiǎn)單的正則表達(dá)式
尖括號(hào)為標(biāo)志赋咽,表達(dá)式寫成<變量類型:變量名>
的形式旧噪,這種正則不需要import額外的方法。
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:id>/vote/', views.vote, name='vote'),
]
變量名所指的變量就作為后面的方法的一個(gè)參數(shù)傳遞過(guò)去脓匿,在views中用形參接收:
def detail(request, id):
return HttpResponse("You're looking at question %s." % id)
def results(request, id):
response = "You're looking at the results of question %s."
return HttpResponse(response % id)
def vote(request, id):
return HttpResponse("You're voting on question %s." % id)
轉(zhuǎn)換格式類型 | 說(shuō)明 |
---|---|
Str | 匹配除分隔符(/)外的非空字符淘钟,默認(rèn)類型<year>等價(jià)于<str:year> |
Int | 匹配0和正整數(shù) |
Slug | 匹配字母、數(shù)字陪毡、橫杠米母、下劃線組成的字符串,str的子集 |
Uuid | 匹配格式化的UUID毡琉,如075194d3-6885-417e-a8a8-6c931e272f00 |
path | 匹配任何非空字符串铁瞒,包括路徑分隔符,是全集 |
re正則表達(dá)式
使用re_path()
代替path()
桅滋,并在字符串的引號(hào)前加r
慧耍。
Python正則表達(dá)式前的 r 表示原生字符串(rawstring),該字符串聲明了引號(hào)中的內(nèi)容表示該內(nèi)容的原始含義丐谋,避免了多次轉(zhuǎn)義造成的反斜杠困擾芍碧。大概意思就是加了r
的不用再考慮字符串中標(biāo)點(diǎn)的轉(zhuǎn)義,程序會(huì)自動(dòng)幫忙轉(zhuǎn)義号俐。知乎-python正則表達(dá)式加了r之后\w,\s,.這些有含義的字符串和沒(méi)有加r的區(qū)別泌豆?
但是筆者發(fā)現(xiàn)加了r
可以激活我安裝的正則表達(dá)式可視化插件,所以還是加上r
吏饿。
提示:
-
使用GET請(qǐng)求獲得參數(shù)時(shí)踪危,斜杠(/)、句點(diǎn)(.)一般不可取到字符串參數(shù)內(nèi)找岖。一串“/”隔開(kāi)的url取參數(shù)需要每個(gè)單獨(dú)取陨倡。如:image.png
- django2.0中,使用正則表達(dá)式進(jìn)行路由的話需要使用re_path()
from django.urls import path, re_path
from . import views
urlpatterns = [
re_path('^hello/$', views.hello),
re_path('^hello/(?P<yy>[0-9]+)/', views.hello),
]
要點(diǎn):
-
匹配頭用尖號(hào)^许布,前部固定兴革,后部自由:
匹配頭 -
匹配尾用$,后部固定,前部自由:
匹配尾和匹配變量 -
匹配變量參數(shù):
字符串:(?P<prm>\w+)杂曲,+表示多個(gè)字符
數(shù)字:(?P<int>\d+)庶艾,+表示多個(gè)數(shù)字
類型、個(gè)數(shù)匹配:(?P<p>[0-9]{4}) //4個(gè)0-9的數(shù)字
尖括號(hào)內(nèi)是變量名擎勘,會(huì)作為views中的方法的參數(shù)傳給views
匹配數(shù)字及個(gè)數(shù)
附:正則表達(dá)式用法小結(jié)
#正則表達(dá)式:
# 元字符: \w \d \s \n \t \W \S \D \b ^ 尖角號(hào) $ . [] [^] () |
# [0-9] \d
# [1-9]
# [\da-zA-Z]
#. :匹配除換行符"\n"以外的任意字符
#\ :轉(zhuǎn)義字符,使后一個(gè)字符改變?cè)瓉?lái)的意思.如果字符串中有字符*需要匹配,可以使用\*或者字符集{*}
#[...]:字符集,對(duì)應(yīng)的位置可以是字符集中任意字符.字符集中的字符可以逐個(gè)列出,也可以給出范圍,如[abc]
#或者是[a-c],第一個(gè)字符如果是^,則表示取反,如[^abc]表示不是abc的其他字符.所有的特殊字符在字符集中
# 都失去其原有的特殊含義.在字符集中如果要使用].-或^,可以在前面加上反斜杠,或者把],-放在第一個(gè)字符,把^
#放在非第一個(gè)字符
#\d 數(shù)字:[0-9]
#\D 非數(shù)字:[^\d]
#\s 空白字符:[<空格> \t\r\n\f\v]
#\S 非空白字符:[^\s]
#\w 單詞字符:[0-9a-zA-Z_]包括了數(shù)字字母下劃線
#\W 非單詞字符:[^\w]
#量詞 : {n} {n,} {n,m} * ? +
#* :匹配前一個(gè)字符0或無(wú)限次 abc*
#+:匹配前一個(gè)字符1次貨無(wú)限次. abc+
#?:匹配前一個(gè)字符0次或1次. abc?
#{n}:匹配前一個(gè)字符n次 ab{2}c 匹配字符:abbc
#{n,}:至少匹配n次,至無(wú)限次
#{n,m}:匹配前一個(gè)字符n到m次 ab{1,2}c 匹配字符abc,abbc
#*?, +?, ?? {m,n}?,使* + ? {m,n}變成非貪婪模式
#邊界匹配:
#^ :匹配字符串開(kāi)頭,
# 在多行模式中匹配每一行的開(kāi)頭. ^abc 匹配字符abc
#$ :匹配字符串末尾,
# 在多行模式中匹配每一行的末尾. abc$ 匹配字符abc
#\A 僅匹配字符串開(kāi)頭 \Aabc 匹配字符abc
#\Z 僅匹配字符串末尾 abc\Z 匹配字符abc
#\b 匹配\w和\W之間 a\b!bc a!bc
# |:|代表左右表達(dá)式任意匹配一個(gè).它總是先嘗試匹配左邊的表達(dá)式
#一旦左邊的表達(dá)式成功匹配則跳過(guò)右邊的表達(dá)式
#如果|沒(méi)有被包括在()中,則它的范圍是整個(gè)正則表達(dá)式 abc|def
#(...) :被括起來(lái)的表達(dá)式將作為分組,從表達(dá)式左邊開(kāi)始每遇到
#一個(gè)分組的左括號(hào)"(",編號(hào)+1.另外,分組表達(dá)式作為一個(gè)整體,可以接數(shù)量詞.
#表達(dá)式中的|僅在該組有效.
#(?P<name>...):分組,除了原有的編號(hào)外再指定一個(gè)額外的別名.
#\<number>:引用編號(hào)為<number>的分組匹配到的字符串. (\d)abc\1
#(?P = name):引用別名為<name>的分組匹配到的字符串
#轉(zhuǎn)義符:
# python str : '\'
# 正則表達(dá)式中的'\'到了python中都會(huì)變成'\\'
# r'\w' 在python當(dāng)中\(zhòng)不轉(zhuǎn)義了,在Python中就是一個(gè)普通的'\',但是在正則表達(dá)式中它還是表示一個(gè)轉(zhuǎn)義符
# 貪婪匹配/惰性匹配 :
# .*x 貪婪 匹配任意內(nèi)容最多次,直到最后一個(gè)X停止 回溯算法
# .*?X 惰性 匹配任意內(nèi)容最少次,遇到第一個(gè)X就停止
# re模塊
# findall 匹配所有 列表
# search 匹配第一個(gè) 變量.group(),沒(méi)匹配到返回None
# match 從頭開(kāi)始匹配第一個(gè)
# split sub subn
# finditer compile
# finditer 返回一個(gè)迭代器,所有匹配到的內(nèi)容需要迭代取到,迭代取到的每一個(gè)結(jié)果都需要group取具體值
# -- 節(jié)省內(nèi)存空間
# compile 編譯,先把一個(gè)正則表達(dá)式編譯,編譯之后,在之后多次使用的過(guò)程不用重新編譯
# -- 節(jié)省時(shí)間 提高效率
# 分組:()
# 1.給不止一個(gè)字符的整體做量詞約束的時(shí)候 www(\.[\w]+)+ www.baidu.com
# 2.優(yōu)先顯示,當(dāng)要匹配的內(nèi)容和不想匹配的內(nèi)容混在一起的時(shí)候,
# 就匹配出所有內(nèi)容,但是對(duì)實(shí)際需要的內(nèi)容進(jìn)行分組
# 3.分組和re模塊中的方法 :
# findall : 分組優(yōu)先顯示 取消(?:正則)
# search :
# 可以通過(guò).group(index)來(lái)取分組中的內(nèi)容
# 可以通過(guò).group(name)來(lái)取分組中的內(nèi)容
# 正則 (?P<name>正則)
# 使用這個(gè)分組 ?P=name
# split : 會(huì)保留分組內(nèi)的內(nèi)容到切割的結(jié)果中