零基礎入手Django(二):url路由配置及渲染方式
今天,小叮當來為大家繼續(xù)分享Django的干貨。

一、url基本概念及格式
想要掌握url不妨回想下我們平時的上網(wǎng)經(jīng)歷。我們平常是怎樣訪問百度的呢?

你很定會說“那還不簡單,只要在瀏覽器里輸個網(wǎng)址,不就行了?”

妥了,你只要知道這個,url便不難理解了,url可類似的看作是一種網(wǎng)址。

1.url基本概念
URL全稱為(UniformResoureLocator)意為“統(tǒng)一資源定位符”。URL是對可以從互聯(lián)網(wǎng)上得到的資源的位置和訪問方法的一種簡潔的表示,是互聯(lián)網(wǎng)上標準資源的地址。

互聯(lián)網(wǎng)上的每個文件都有一個唯一的URL,它包含的信息指出文件的位置以及瀏覽器應該怎么處理它。
2.url格式
url的格式如下:
schema://host[:port#]/path/.../[?query-string][#anchor]
看到這兒,你可能有點懵,沒關系,我們舉個例子,你就會有豁然開朗的感覺。

就以我們上次配置的django項目中的hello網(wǎng)址為例:
“http://192.168.255.130:8000/hello/”
(1)schema(協(xié)議):http
? (2)host(主機,常指服務器主機):192.168.255.130
(3)port(端口):8000
(4)path(路徑):hello/
3.urls.py的作用
經(jīng)過上次的hello_django配置,相必大家已基本了解urls.py的作用,簡單來說就是配置url,以供用戶訪問。

URL配置(URLconf)就像是Django所支撐網(wǎng)站的目錄。它的本質(zhì)是URL模式以及要為該URL模式調(diào)用的視圖函數(shù)之間的映射表。

以這樣的方式告訴Django,對于那個URL調(diào)用那段代碼。url的加載就是從配置文件中開始的。

要上述內(nèi)容不易理解,不妨這樣認為,“urls.py就是為url定義路徑,并調(diào)用視圖函數(shù)以返回頁面,呈現(xiàn)給用戶?!?/p>
二、path和re_path
1.path傳參
例如,我的視圖函數(shù)返回的是
當我想顯示python、tornado、flask項目時該怎么辦?難道要再寫3個視圖函數(shù)嗎?這么麻煩,我是絕對不會寫的。。。

這時,就需要path傳參來幫助我們了。
(1)在urls.py中設置參數(shù)
path的基本規(guī)則如下:
使用尖括號(<>)從url中捕獲值。包含一個轉(zhuǎn)化器類型(convertertype)
沒有轉(zhuǎn)化器,將匹配任何字符串,包括/ 字符
參數(shù)規(guī)則為/<參數(shù)名稱>/,如下/<project>/
當前面的url匹配成功后就會調(diào)用后面的視圖函數(shù)hello

(2)在views.py的對應視圖函數(shù)中,寫入相應的參數(shù),并應用

值得注意的是,視圖函數(shù)中的名稱要與urls.py中配置的一致。
(3)服務啟動后,在瀏覽器中輸入對應項目名稱以查看
輸入"http://192.168.255.130:8000/hello/django/"
結果顯示為

輸入"http://192.168.255.130:8000/hello/tornado/"
結果顯示為

輸入”http://192.168.255.130:8000/hello/python/“
結果顯示為

其中值得注意的是,參數(shù)默認的是字符類型,若要限定參數(shù)為純數(shù)字,在參數(shù)前加上int轉(zhuǎn)換器,用冒號隔開即可。
如下所示

我們再次運行,在瀏覽器中查看,
仍輸入”http://192.168.255.130:8000/hello/django/“
此時發(fā)現(xiàn),頁面尋找不到,報錯為當前路徑不匹配。這說明只有當你輸入的url跟后臺配置的url一致時,才會調(diào)用url對應的視圖函數(shù)。

我們運行數(shù)字,
仍輸入”http://192.168.255.130:8000/hello/12306/“
此時,頁面成功運行

除了int轉(zhuǎn)換器外,Django2.0默認支持的常用轉(zhuǎn)換器還有
str,匹配除了路徑分隔符(/)之外的非空字符串,這是默認的形式 int,匹配正整數(shù),包含0。 slug,匹配字母、數(shù)字以及橫杠、下劃線組成的字符串。 uuid,匹配格式化的uuid,如?075194d3-6885-417e-a8a8-6c931e272f00。 path,匹配任何非空字符串,包含了路徑分隔符
2.re_path正則匹配
值得注意的是,Django2.0的re_path和Djano1.11的urls是相同的。
我們首先在urls.py的django.urls包中導入re_path

在views.py中定義新的視圖函數(shù),供re_path調(diào)用

代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' __time__?=?'2019-01-10?14:19' from?django.http?import?HttpResponse def?hello(request,project): ????return?HttpResponse('大家好我是IT小叮當,我在編寫%s項目!'%project) def?xdd(request): ????return?HttpResponse('大家好我是IT小叮當,我18歲了!')
在urls.py中使用re_path調(diào)用新建的視圖函數(shù)xdd

代碼如下:
from?django.contrib?import?admin from?django.urls?import?path,re_path from?.views?import?* urlpatterns?=?[ ????path('admin/',?admin.site.urls), ????path('hello/<int:project>/',hello), ????re_path('xdd/',xdd) ]
啟動服務器后
在瀏覽器中輸入“http://192.168.255.130:8000/xdd/”進行訪問

貌似一切正常,但,當我們在xdd前輸入亂碼時,竟也可以訪問!
輸入的網(wǎng)址為”http://192.168.255.130:8000/qinfenxuexifdxdd/“

我們在xdd/后輸入亂碼時,也可訪問??!
輸入的網(wǎng)址為”?http://192.168.255.130:8000/xdd/sdfsdf “

這是因為,正則匹配時,只寫一個字符串,表示的是包含關系。當我們使用re_path時,只寫了”xdd/",所以只要地址中包含“xdd/”的均可就返回視圖函數(shù)。
當我們需要限定訪問路徑為“xdd/”時,就需要加上正則表達式來進行規(guī)范。
將urls.py中的路徑修改為
正則表達式中“^”表示,以某某開頭;”$“表示以某某結尾。

在瀏覽器中驗證
輸入”http://192.168.255.130:8000/xdd/“,顯示為

輸入”http://192.168.255.130:8000/sdsxdd/ “,結果顯示為

輸入” http://192.168.255.130:8000/xdd/sd“,結果顯示為

可見此時,通過正則表達式,已達到我們的需求。但也足以可見此過程,十分復雜!這也就是許多人喜歡Django2.0而不喜歡Django1.11的緣故了。
re_path傳參
當我們需要用re_path傳參時,仍需要正則表達式。
首先,定義視圖函數(shù)xdd2

代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' __time__?=?'2019-01-10?14:19' from?django.http?import?HttpResponse def?hello(request,project): ????return?HttpResponse('大家好我是IT小叮當,我在編寫%s項目!'%project) def?xdd(request): ????return?HttpResponse('大家好我是IT小叮當,我18歲了!') def?xdd2(request,age): ????return?HttpResponse('大家好我是IT小叮當,我%s歲了!'%age)
在urls.py中用正則表達式配置路徑

代碼如下:
from?django.contrib?import?admin from?django.urls?import?path,re_path from?.views?import?* urlpatterns?=?[ ????path('admin/',?admin.site.urls), ????path('hello/<int:project>/',hello), ????re_path('^xdd/$',xdd), ????re_path('^xdd2/(?P<age>[0-9]+)/',xdd2), ]
在正則表達式中
"?p<age>"表示命名一個名字為age的組,匹配規(guī)符合后面的"[0-9]+"規(guī)則
”[0-9]+“表示[0-9]中的數(shù)字,至少取一個。
重啟服務后,在瀏覽器中檢驗
輸入”?http://192.168.255.130:8000/xdd2/18/”,結果顯示為

輸入“http://192.168.255.130:8000/xdd2/20/ ”,結果顯示為

輸入非數(shù)字“http://192.168.255.130:8000/xdd2/ssd”,結果顯示為

由此可說明,通過re_path方式的純數(shù)字傳參配置成功!
三、模板路徑配置
1.include分配路由
當一個項目中,需要較多的視圖時,urls.py中則需要配置很多的路徑,如果都寫在urls.py中時,不僅雜亂無章,而且不便于后期的維護管理。

這時,我們便可用include來進行“分路由”式的管理,來解決這個問題。我們以主路由管理“book"app下的分路由為例進行說明。
(1)在”book"app的視圖views.py中新建視圖函數(shù)

代碼如下:
from?django.shortcuts?import?render from?django.http?import?HttpResponse #?Create?your?views?here. def?book_index(request): ????return?HttpResponse('這是小叮當返回的book的主頁')
(2)在我們新建好的名為“book”的app中新建一個urls.py

在“book”app的urls.py中輸入以下代碼
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' __time__?=?'2019-01-11?17:42' from?django.urls?import?path from?.?import??views urlpatterns=[ ????path('index/',views.book_index), ]
界面如下:

(3)在主目錄下的urls.py中通過django.urls包導入include,設置分路由

如下:
在路經(jīng)中添加如下代碼:
表示主路由分配的路徑為"book/",通過include后,關聯(lián)名為book的app
中的urls.py中的路由。
在瀏覽器中檢查結果
輸入:
“http://192.168.255.130:8000/book/index/”
結果顯示為

這說明我們已通過include配置好了相應的分路由地址。
2.kwargs傳參
經(jīng)過前面的學習,我們已知道可以通過“/<>/”的方式在路由中傳參,讓視圖函數(shù)進行接受。下面我們來了解一下另一中傳參方式:kwargs
kwargs(?全稱為?key word args),或關鍵字(鍵值對的形式)傳參,亦可理解為“字典傳參”
(1)我們在“book"app的urls.py的路徑中傳參如下:
向book_index視圖函數(shù)傳了一個字典參數(shù){‘test’:'true'}

代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' __time__?=?'2019-01-11?17:42' from?django.urls?import?path from?.?import??views urlpatterns=[ ????path('index/',views.book_index,{'test':'ture'}), ]
(2)在對應視圖函數(shù)中,通過”**kwargs“進行接收。

具體代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' from?django.shortcuts?import?render from?django.http?import?HttpResponse #?Create?your?views?here. #通過kwargs.get()的方法獲取值 def?book_index(request,**kwargs): ????value=kwargs.get('test') ????return?HttpResponse('這是小叮當返回的book的主頁,我獲取到參數(shù)是%s'%value)
在瀏覽器中檢測
輸入”http://192.168.255.130:8000/book/index/“
顯示結果為

值得注意的是,當在”主路由“中,以這樣的方式傳參時,所有的分路由就被**kwargs批量傳參了。.

分路由的視圖函數(shù),均要加上”**kwargs“接受參數(shù)才行,否則便會報錯。

報錯為

修改視圖函數(shù),加上”**kwargs“后

結果正常顯示

3.使用name和reverse進行頁面重定向
當我們制作了新的頁面配置了新的url,并想使舊的url重定向到新的頁面時,使用name和reverse可大大簡化我們的步驟。
(1)關于重定向

(2)在"book"app中新建兩個視圖函數(shù)atrticle1和article2

代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' from?django.shortcuts?import?render from?django.http?import?HttpResponse #?Create?your?views?here. def?book_index(request,**kwargs): ????value=kwargs.get('test') ????return?HttpResponse('這是小叮當返回的book的主頁,我獲取到參數(shù)是%s'%value) def?book_index2(request,**kwargs): ????return?HttpResponse('這是小叮當返回的book的主頁2,我獲取到參數(shù)') def?article(request,**kwargs): ????????return?HttpResponse('這是小叮當?shù)奈恼马撁?#39;) def?article2(request,?**kwargs): ????return?HttpResponse('這是小叮當?shù)男滦滦挛恼马撁?#39;)
添加對應的路由

代碼如下:
#!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' #!/usr/bin/env?python #?-*-?coding:utf-8?-*-?? __author__?=?'IT小叮當' __time__?=?'2019-01-11?17:42' from?django.urls?import?path from?.?import??views urlpatterns=[ ????path('index/',views.book_index,{'test':'ture'}), ????path('index2/',?views.book_index2), ????path('article/',?views.article), ????path('article2/',?views.article2), ]
在瀏覽中訪問如下
輸入“http://192.168.255.130:8000/book/article/”,顯示為

輸入“http://192.168.255.130:8000/book/article2/”,顯示為

(3)在"book"app下的views.py中,通過django.shortcus導入redirect

更改article視圖函數(shù)

代碼如下:
? ? ? ?return redirect('/book/article2')
再次在瀏覽器中輸入“http://192.168.255.130:8000/book/article/”

點擊回車,便可發(fā)現(xiàn)其已自動重定向到新的article2頁面

當我們在"book"app的urls中修改路徑名稱,而不想在redict中更改過多時,我們便會使用name和reverse
首先,在“book”app中的urls.py中為需要重定向的頁面路徑加上name屬性,如下
然后,在“book”app的views.py中導入reverse
重新定義視圖函數(shù)

代碼如下
? ? ? ?return redirect(reverse('article2'))
其中reverse函數(shù)的作用就是轉(zhuǎn)化,就是將名字為“article2”的路由地址給轉(zhuǎn)換出來。
我們?nèi)栽跒g覽器中輸入“http://192.168.255.130:8000/book/article/”

發(fā)現(xiàn),其自動轉(zhuǎn)到了新配置好的路由頁面地址

當你真正了解原理后,你會發(fā)現(xiàn),以上過程可總結為一句話:
利用name給url起名字,在視圖函數(shù)中通過reverse使用name將路由還原出來。
四、模板渲染方式
所謂模板渲染,也就是模板顯示,在django項目中顯示html文件。
如果是以命令行創(chuàng)建的django項目,則不會帶有templates模板文件目錄,需要我們自己創(chuàng)建。(pycharm創(chuàng)建django項目可選擇創(chuàng)建)

1.創(chuàng)建模板目錄和對應項目html文件
首先,在項目目錄下右鍵“new”--"Directory"? (新建目錄)

取名為“templates”(模板)

根據(jù)項目的app在templates下創(chuàng)建同名文件,例如“hello_django”項目中有“book”和“movie”這兩個app,那么就在templates文件夾下創(chuàng)建“book”和“movie”文件夾,用來存放各自的模板文件。

在templates下的book中新建html文件,用來作為“”book“app的主頁。

起名為“index”

創(chuàng)建完成后,編輯index.html文件。
2.通過settings.py文件配置項目模板路徑
在項目settings.py中找到"TEMPLATES"下的“DIRS”,將項目中的“templates”的文件位置放入其中。

在其中輸入“os.path.join(BASE_DIR,'templates')”即可。
其界面如下

其中“BASE_DIR”指django項目的位置,在settings.py的開頭部分,系統(tǒng)已自動定義好。

最后將配置好的項目文件,上傳到ubuntu服務器

下方一般有上傳成功的提示

3.渲染方式一
進入對應app的views.py中,導入get_template包,以”book"為例。
創(chuàng)建相應的視圖函數(shù)
? ?t=get_template('book/index.html')
#通過render傳參name
? ?html=t.render({'name':'IT小叮當'})
? ?return HttpResponse(html)
值得注意的是,get_template()中傳的是index.html在templates文件夾下位置所在,因為我們?yōu)橄到y(tǒng)配置的路徑只能識別到templates文件夾
對應的html
<html lang="en">
<head>
? ?<meta charset="UTF-8">
? ?<title>book首頁</title>
</head>
<body>
歡迎來到小叮當?shù)腷ook首頁!
我是小叮當{{name }}
</body>
</html>
在urls.py中配置對應的path
如下

瀏覽器中查看

4.渲染方式二
直接使用系統(tǒng)導入的render函數(shù)

views.py中定義視圖函數(shù)index3
def?index3(request,**kwargs): ????return?render(request,'book/index.html',context={'name':'IT小叮當渲染方式二'})
值的注意的是,在模版(html)中向視圖函數(shù)傳參時,要使用到“context"
urls.py中配置路由
瀏覽器中查看
