Django視圖層與模板層實(shí)例詳解_第1頁(yè)
Django視圖層與模板層實(shí)例詳解_第2頁(yè)
Django視圖層與模板層實(shí)例詳解_第3頁(yè)
Django視圖層與模板層實(shí)例詳解_第4頁(yè)
Django視圖層與模板層實(shí)例詳解_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第Django視圖層與模板層實(shí)例詳解目錄theme:channing-cyan網(wǎng)頁(yè)偽靜態(tài)視圖層1.視圖函數(shù)的返回值問(wèn)題2.視圖函數(shù)返回json格式數(shù)據(jù)3.form表單攜帶文件數(shù)據(jù)4.FBV與CBV5.CBV源碼分析模板層1.模板語(yǔ)法傳值2.模板語(yǔ)法傳值的范圍3.模板語(yǔ)法值過(guò)濾器4.模板語(yǔ)法標(biāo)簽(類(lèi)似于python中的流程控制)5.自定義標(biāo)簽函數(shù)、過(guò)濾器、inclusion_tag6.模板的繼承7.模板的導(dǎo)入

theme:channing-cyan

網(wǎng)頁(yè)偽靜態(tài)

將動(dòng)態(tài)網(wǎng)頁(yè)偽裝成靜態(tài)網(wǎng)頁(yè),可以提升網(wǎng)頁(yè)被搜索引擎檢索道德概率

表現(xiàn)形式為:網(wǎng)址看著像是一個(gè)具體的文件路徑例如::8001/admin/login/

path(index.html,views.index)

視圖層

1.視圖函數(shù)的返回值問(wèn)題

當(dāng)我們?cè)趘iews.py定義的視圖函數(shù)不設(shè)置返回值時(shí),可以看到django報(bào)了以下錯(cuò)誤:

報(bào)錯(cuò)信息:

Theviewapp01.views.homedidntreturnanHttpResponseobject.ItreturnedNoneinstead.

視圖app01.views.home沒(méi)有返回HttpResponse對(duì)象。它返回None。

由此我們可以猜測(cè)一個(gè)結(jié)論:視圖函數(shù)必須返回一個(gè)HttpResponse對(duì)象我們ctrl+左鍵進(jìn)入HttpResponse可以發(fā)現(xiàn)它是一個(gè)類(lèi):

classHttpResponse(HttpResponseBase):

pass

可是視圖函數(shù)還可以返回render和redirect對(duì)象啊,我們進(jìn)入到這兩個(gè)函數(shù)中一探究竟:

defrender(...):

pass

returnHttpResponse(content,content_type,status)

render函數(shù)返回值也是HttpResponse對(duì)象。再來(lái)看看redirect:

defredirect(to,*args,permanent=False,**kwargs):

redirect_class=HttpResponsePermanentRedirectifpermanentelseHttpResponseRedirect

returnredirect_class(resolve_url(to,*args,**kwargs))

redirect函數(shù)返回值也是HttpResponse對(duì)象。

由此可見(jiàn),views.py中的視圖函數(shù)都必須返回一個(gè)HttpResponse對(duì)象

2.視圖函數(shù)返回json格式數(shù)據(jù)

需求:將字典數(shù)據(jù)序列化成json字符串傳給前端::

方法1:利用json模塊

defhome(request):

importjson

user_dict={'name':'jason老師','pwd':123,'hobby':['read','run','music']}

json_user_dict=json.dumps(user_dict,ensure_ascii=False)

returnrender(request,'home.html',json_user_dict)

方法2:利用JsonResponse

fromdjango.httpimportJsonResponse

defhome(request):

JsonResponse(user_dict)#

只用一行代碼就頂替了上述方法三行代碼,非常好用。但有個(gè)問(wèn)題,JsonResponse沒(méi)有ensure_ascii參數(shù),也就意味著我們暫時(shí)無(wú)法阻止?jié)h字編碼。想要解決這個(gè)問(wèn)題,主要我們查看JsonResponse的源碼:

classJsonResponse(HttpResponse):

def__init__(self,data,encoder=DjangoJSONEncoder,safe=True,

json_dumps_params=None,**kwargs):

ifjson_dumps_paramsisNone:

json_dumps_params={}

kwargs.setdefault('content_type','application/json')

data=json.dumps(data,cls=encoder,**json_dumps_params)

super().__init__(content=data,**kwargs)

可以看到JsonResponse內(nèi)部是有json.dumps方法的,但這個(gè)方法需要傳一些特殊的參數(shù):

**json_dumps_params。這個(gè)參數(shù)用來(lái)接收多余的關(guān)鍵字參數(shù)并將其打散成一個(gè)個(gè)的k:v鍵值對(duì)。而這些關(guān)鍵字需要我們當(dāng)做json_dumps_params的值,以字典的形式傳入。

于是:

JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})

這就相當(dāng)于我們?cè)O(shè)置了**ensure_ascii:False**但是設(shè)置這個(gè)參數(shù)的過(guò)程屬實(shí)有點(diǎn)坎坷~~

除了字典類(lèi)型,其他容器類(lèi)型也可以被序列化,不過(guò)要指定safe參數(shù)為False

3.form表單攜帶文件數(shù)據(jù)

form表單需要設(shè)置的參數(shù):

formmethod="post"enctype="multipart/form-data"

/form

后端獲取文件代碼:

files=request.FILES#后端接收文件數(shù)據(jù)只能用FILES方法,不能用POST

4.FBV與CBV

FBV:基于函數(shù)的視圖

#views.py

defhome(request):

returnrender(request,'home.html')

#urls.py

path('home/',views.home)

CBV:基于類(lèi)的視圖CBV會(huì)根據(jù)請(qǐng)求方式的不同自動(dòng)匹配類(lèi)中定義的方法并自動(dòng)執(zhí)行

#views.py

fromdjangoimpostviews

classMyView(views.View):

defget(self,request):

returnHttpResponse('我是CBV的get方法')

defpost(self,request):

returnHttpResponse('我是CBV的post方法')

#urls.py

path('func/',views.MyView.as_view())

5.CBV源碼分析

源碼分析入口:

path(func/,views.MyView.as_view())

1.綁定給類(lèi)的as_view()方法

defas_view(...):

defview(...):

pass

returnview

此時(shí)路由匹配代碼的本質(zhì):path(func/,views.view())

由此可見(jiàn),CBV與FBV路由匹配的原理是一樣的

2.path(func/,views.view())

這句代碼的意思是:只要我們?cè)L問(wèn)了func地址,會(huì)立即執(zhí)行后面的views.view()

3.進(jìn)入view()函數(shù):

defview(request,*args,**kwargs):

self=cls(**initkwargs)#這里的cls使我們自己寫(xiě)的類(lèi)MyViewself是MyView實(shí)例化出來(lái)的

對(duì)象obj這一句相當(dāng)于obj=MyView()

returnself.dispatch(request,*args,**kwargs)#這一句相當(dāng)于obj.dispatch()

4.進(jìn)入dispatch函數(shù)

defdispatch(self,request,*args,**kwargs):

#dispatch是綁定給對(duì)象的方法,self相當(dāng)于是我們前文提到的obj

ifrequest.method.lower()inself.http_method_names:

handler=getattr(self,request.method.lower(),self.http_method_not_allowed)

#反射通過(guò)請(qǐng)求字符串去調(diào)用真正的請(qǐng)求方法這里的請(qǐng)求是post所以handler是post

else:

handler=self.http_method_not_allowed

returnhandler(request,*args,**kwargs)#即post(request,*args,**kwargs)

#此時(shí)view()函數(shù)的返回值為:

#defview(request,*args,**kwargs):

#returnself.post(request,*args,**kwargs)

模板層

1.模板語(yǔ)法傳值

方式1:指名道姓地傳值。好處是不浪費(fèi)資源,壞處是值過(guò)多時(shí)不方便

defhome(request):

name='kevin'

age=19

returnrender(request,'home.html',{'name':name,'age':age})

方式2:關(guān)鍵字locals()。可以將整個(gè)視圖函數(shù)名稱空間中所有的名字全部傳入,簡(jiǎn)單快捷,壞處是有冗余

defhome(request):

name='kevin'

age=19

returnrender(request,'home.html',locals())

2.模板語(yǔ)法傳值的范圍

1.基本數(shù)據(jù)類(lèi)型都可以傳遞

2.函數(shù)名的傳遞會(huì)自動(dòng)加括號(hào)執(zhí)行并將結(jié)果展示到頁(yè)面上(注意函數(shù)如果有參數(shù)則不會(huì)執(zhí)行也不會(huì)展示,模板語(yǔ)法不支持參數(shù))

3.類(lèi)名的傳遞也會(huì)自動(dòng)加括號(hào)調(diào)用并將實(shí)例化出的對(duì)象展示到頁(yè)面上(模板語(yǔ)法會(huì)自動(dòng)判斷每一個(gè)名字是否能被加括號(hào)調(diào)用,如果可以則自動(dòng)調(diào)用)

4.對(duì)象的傳遞可以直接用句點(diǎn)符點(diǎn)出對(duì)象的屬性

5.django的模板語(yǔ)法在操作容器類(lèi)型時(shí)只能用句點(diǎn)符操作(操作列表用.數(shù)字的形式)

3.模板語(yǔ)法值過(guò)濾器

過(guò)濾器類(lèi)似于python中的內(nèi)置函數(shù)

p統(tǒng)計(jì)長(zhǎng)度:{{s|length}}/p

p加法運(yùn)算:{{s|add:'NB'}}/p

p文件大小:{{file_size|filesizeformat}}/p

p數(shù)據(jù)切片:{{s|slice:'3'}}/p

p字符截?。簕{s|truncatechars:3}}/p#以字符為單位多出的部分用...代替

p單詞截取:{{words|truncatewords:3}}/p#以單詞為單位多出的部分用...代替

p語(yǔ)法轉(zhuǎn)義:{{html_tag|safe}}/p#識(shí)別字符串中的html標(biāo)簽并渲染(默認(rèn)是不識(shí)別)

#html默認(rèn)不識(shí)別后端傳過(guò)來(lái)的字符串標(biāo)簽,指定safe可以讓其識(shí)別并渲染

#除了在傳給前端之后讓前端識(shí)別我們也可以在后端處理之后再傳給前端,這樣前端就不用識(shí)別了(意味著html頁(yè)面上的數(shù)據(jù)不一定非要在html文件中編寫(xiě)了也可以通過(guò)后端傳入)

fromdjango.utils.safestringimportmark_safe

script_tag1='scriptalert(666)/script'

res=mark_safe(script_tag1)#直接把res傳給前端

'''

django模板語(yǔ)法中的符號(hào)就兩個(gè)一個(gè){{}}一個(gè){%%}

需要使用數(shù)據(jù)的時(shí)候{{}}

需要使用方法的時(shí)候{%%}

4.模板語(yǔ)法標(biāo)簽(類(lèi)似于python中的流程控制)

if標(biāo)簽:

{%if條件%}條件一般是后端傳過(guò)來(lái)的數(shù)據(jù)直接寫(xiě)名字使用即可

條件成立執(zhí)行的代碼

{%elif條件1%}

條件1成立執(zhí)行的代碼

{%else%}

條件都不成立執(zhí)行的代碼

{%endif%}

for標(biāo)簽

{%foriinf%}

{%ifforloop.first%}

p這是第一次/p

{%elifforloop.last%}

p這是最后一次/p

{%else%}

p啥也不是{{i}}/p

{%endif%}

{%empty%}

p你給我的是個(gè)空怎么for循環(huán)呢/p

{%endfor%}

for循環(huán)可用的一些參數(shù)

VariableDescriptionforloop.counter當(dāng)前循環(huán)的索引值(從1開(kāi)始)forloop.counter0當(dāng)前循環(huán)的索引值(從0開(kāi)始)forloop.revcounter當(dāng)前循環(huán)的倒序索引值(從1開(kāi)始)forloop.revcounter0當(dāng)前循環(huán)的倒序索引值(從0開(kāi)始)forloop.first當(dāng)前循環(huán)是不是第一次循環(huán)(布爾值)forloop.last當(dāng)前循環(huán)是不是最后一次循環(huán)(布爾值)forloop.parentloop本層循環(huán)的外層循環(huán)

5.自定義標(biāo)簽函數(shù)、過(guò)濾器、inclusion_tag

如果想實(shí)現(xiàn)自定義,必須先做以下幾件事

1.在應(yīng)用下創(chuàng)建一個(gè)名為templatetags的文件夾2.在該文件夾下創(chuàng)建任意名稱的.py文件3.在該py文件內(nèi)編寫(xiě)自定義相關(guān)代碼

fromdjango.templateimportLibrary

register=Library()

自定義過(guò)濾器

@register.filter(name='myfilter')

defmy_add(a,b):

returna+b

自定義標(biāo)簽函數(shù)

@register.simple_tag(name='mt')

deffunc(a,b,c,d):

returna+b+c+d

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論