作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉(zhuǎn)載,也請(qǐng)保留這段聲明。謝謝糠排!
模板使用
之前是采用HttpResponse直接返回一些字符串傍衡,我們可以看到數(shù)據(jù)和視圖是混合的
# return HttpResponse("<p> Hello ,world!</p>")
模板可以實(shí)現(xiàn)數(shù)據(jù)與視圖分離
創(chuàng)建存放模板目錄:
# mkdir templates/west -p
創(chuàng)建模板文件:
# vim templates/west/templay.html
# <h1>{{ label }}</h1>
標(biāo)簽已經(jīng)標(biāo)明在模板文件中
需要設(shè)置django搜索模板文件路徑:mysite/setting.py
# 'DIRS': (os.path.join(BASE_DIR,'templates/west'),),
添加構(gòu)建http響應(yīng)方法,wests/view.py:
# def templay(request):
# context = {}
# context['label'] = 'hello,world!'
# return render(request, 'templay.html', context)
添加url匹配規(guī)則:
# url(r'^templay/','west.views.templay'),
測(cè)試:
# neo@neo-virtual-machine:~$ curl http://127.0.0.1:8000/west/templay/
# <h1>hello,world!</h1>
流程
模板將視圖和數(shù)據(jù)分離開(kāi)來(lái)
如果將數(shù)據(jù)庫(kù)的數(shù)據(jù)放入到context中区匠,就可以實(shí)現(xiàn)查看數(shù)據(jù)庫(kù)的內(nèi)容
# def staff(request):
# staff_list = Character.objects.all()
# staff_str = map(str, staff_list)
# context = {'label': ' '.join(staff_str)}
# return render(request, 'templay.html', context)
循環(huán)與選擇
上面的方式臭觉,都是通過(guò)組合成字符串的方式,返回結(jié)果辱志,staff實(shí)際上是一個(gè)數(shù)據(jù)容器(可迭代對(duì)象)蝠筑,我們也可以直接返回一個(gè)容器,在templay.html文件循環(huán)之后揩懒,顯示
# def staff(request):
# staff_list = Character.objects.all()
# return render(request, 'templay.html',{'staffs': staff_list})
修改templay.html模板文件什乙,循壞容器數(shù)據(jù)之后,在顯示
# {% for item in staffs %}
# <p> {{ item.id }},{{ item }} </p>
# {% endfor %}
測(cè)試:
# neo@neo-virtual-machine:~$ curl http://127.0.0.1:8000/west/staff/
# <p> 1,ruiwen </p>
# <p> 2,namei </p>
# <p> 3,fatiao </p>
選擇結(jié)構(gòu):
# {% if condition1 %}
# ... display 1
# {% elif condiiton2 %}
# ... display 2
# {% else %}
# ... display 3
# {% endif %}
elif 與 else 可以省略
模板與繼承
模板可以采用繼承的方式實(shí)現(xiàn)復(fù)用已球,測(cè)試采用templay.html來(lái)繼承base.html臣镣,使用base.html的主體,只替換特定部分的內(nèi)容智亮。
新建templates/west/base.html文件
# <html>
# <head>
# <title>templay</title>
# </head>
# <body>
# <h1>come from base.html</h1>
# {% block mainbody %}
# <p>original</p>
# {% endblock %}
# </body>
# </html>
名為mainbody的block標(biāo)簽是可以被繼承者替換掉的部分
在tmplay.html中繼承base.html
html表格
web客戶(hù)端發(fā)送請(qǐng)求忆某,在請(qǐng)求中附加數(shù)據(jù),服務(wù)器通過(guò)解析請(qǐng)求阔蛉,獲得客戶(hù)端數(shù)據(jù)弃舒,根據(jù)URL來(lái)提供特定的服務(wù)。
HTML表格的目的是幫助用戶(hù)構(gòu)成HTTP請(qǐng)求状原,把數(shù)據(jù)用GET或者POST的方法傳遞給某一URL地址聋呢。
# <form action="/west/investigate/" method="get">
# <input type="text" name="staff">
# <input type="submit" value="Submit">
# <form>
示例中,form標(biāo)簽有兩個(gè)屬性颠区,一個(gè)是action用來(lái)說(shuō)明url地址削锰,一個(gè)是method說(shuō)明請(qǐng)求的方法。
input標(biāo)簽是輸入欄目毕莱,根據(jù)type的不同器贩,第一個(gè)為文本框,第二個(gè)為提交按鈕朋截,name為輸入欄的名字蛹稍,服務(wù)器在解析數(shù)據(jù)時(shí),將以name為索引质和。value表示按鈕顯示的值稳摄。
修改west/views.py文件:
# def form(request):
# return render(request,'form.html')
修改urls.py,對(duì)west/form的訪(fǎng)問(wèn)饲宿,指向form該視圖
GET方法
表格中的數(shù)據(jù)是通過(guò)GET方法提交的厦酬,我們可以通過(guò)request.GET['staff'] 胆描,來(lái)獲得name為staff的輸入欄數(shù)據(jù),該數(shù)據(jù)是一個(gè)字符串仗阅,我們可以利用investigate()將直接顯示該字符串昌讲。
設(shè)置west/views.py
# def investigate(request):
# rlt = request.GET['staff']
# return HttpResponse(rlt)
設(shè)置west/urls.py,設(shè)置對(duì)west/investigate的訪(fǎng)問(wèn)指定對(duì)應(yīng)的視圖
# url(r'^investigate/', 'west.views.investigate'),
訪(fǎng)問(wèn)west/form/就會(huì)顯示輸入欄和提交按鈕减噪,
當(dāng)輸入一些字符串之后短绸,在提交,就會(huì)跳轉(zhuǎn)到investigate筹裕,顯示你輸入的數(shù)據(jù)醋闭。
# http://127.0.0.1:8000/west/investigate/?staff=test
POST方法
(搜索一下GET與POST的區(qū)別)
用一個(gè)URL和處理函數(shù),同時(shí)顯示視圖和處理請(qǐng)求朝卒。
創(chuàng)建investigate.html模板:
# <form action="/west/investigate/" method="post">
# {% csrf_token %}
# <input type="text" name="staff">
# <input type="submit" value="submit">
# </form>
# <p> {{ rlt }}</p>
我們修改提交表格的方法為post证逻。在模板的末尾,我們?cè)黾右粋€(gè)rlt記號(hào)抗斤,為表格處理結(jié)果預(yù)留位置囚企。
表格后面還有一個(gè){% csrf_token %}的標(biāo)簽。csrf全稱(chēng)是Cross Site Request Forgery瑞眼。這是Django提供的防止偽裝提交請(qǐng)求的功能龙宏。POST方法提交的表格,必須有此標(biāo)簽伤疙。
在west/views.py中银酗,用investigate()來(lái)處理表格:
# def investigate(request):
# ctx = {}
# ctx.update(csrf(request))
# if request.POST:
# ctx['rlt'] = request.POST['staff']
# return render(request, "investigate.html",ctx)
csrf()和{% csrf_token%}對(duì)應(yīng)起來(lái)。
判斷是否存在POST方法掩浙,匹配到staff將數(shù)據(jù)讀取花吟,在往頁(yè)面顯示數(shù)據(jù)。
存儲(chǔ)數(shù)據(jù)
將客戶(hù)端瀏覽器提交的數(shù)據(jù)存入數(shù)據(jù)庫(kù)中厨姚,將字符串存入模型Character
修改west/views.py的investigate():
# def investigate(request):
# if request.POST:
# submitted = request.POST['staff']
# new_record = Character(name = submitted)
# new_record.save()
# ctx = {}
# ctx.update(csrf(request))
# all_records = Character.objects.all()
# ctx['staff'] = all_records
# return render(request, "investigate.html", ctx)
在POST的處理部分,我們調(diào)用Character類(lèi)創(chuàng)建新的對(duì)象键菱,并讓該對(duì)象的屬性name等于用戶(hù)提交的字符串谬墙。通過(guò)save()方法,我們讓該記錄入庫(kù)经备。
隨后拭抬,我們從數(shù)據(jù)庫(kù)中讀出所有的對(duì)象,并傳遞給模板侵蒙。
我們還需要修改模板investigate.html造虎,以更好的顯示:
# <form action="/west/investigate/" method="post">
# {% csrf_token %}
# <input type="text" name="staff">
# <input type="submit" value="submit">
# </form>
# {% for person in staff %}
# <p> {{ person }}</p>
# {% endfor %}
測(cè)試:
點(diǎn)擊submit顯示數(shù)據(jù)庫(kù)name字段內(nèi)容,在輸入欄輸入數(shù)據(jù)之后纷闺,在點(diǎn)擊submit算凿,程序會(huì)將數(shù)據(jù)先存入到后臺(tái)數(shù)據(jù)庫(kù)份蝴,接著在讀取數(shù)據(jù)庫(kù)內(nèi)容顯示。
表格對(duì)象
客戶(hù)提交數(shù)據(jù)后氓轰,服務(wù)器往往需要對(duì)數(shù)據(jù)做一些處理婚夫。比如檢驗(yàn)數(shù)據(jù),看是否符合預(yù)期的長(zhǎng)度和數(shù)據(jù)類(lèi)型署鸡。在必要的時(shí)候案糙,還需要對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,比如從字符串轉(zhuǎn)換成整數(shù)靴庆。這些過(guò)程通常都相當(dāng)?shù)姆爆崱?br>
Django提供的數(shù)據(jù)對(duì)象可以大大簡(jiǎn)化這一過(guò)程时捌。該對(duì)象用于說(shuō)明表格所預(yù)期的數(shù)據(jù)類(lèi)型和其它的一些要求。這樣Django在獲得數(shù)據(jù)后炉抒,可以自動(dòng)根據(jù)該表格對(duì)象的要求奢讨,對(duì)數(shù)據(jù)進(jìn)行處理。
修改west/views.py:
# from django.shortcuts import render
# from django.core.context_processors import csrf
# from west.models import Character
# from django import forms
# class CharacterForm(forms.Form):
# name = forms.CharField(max_length = 200)
# def investigate(request):
# if request.POST:
# form = CharacterForm(request.POST)
# if form.is_valid():
# submitted = form.cleaned_data['name']
# new_record = Character(name = submitted)
# new_record.save()
# form = CharacterForm()
# ctx ={}
# ctx.update(csrf(request))
# all_records = Character.objects.all()
# ctx['staff'] = all_records
# ctx['form'] = form
# return render(request, "investigate.html", ctx)
上面定義了CharacterForm類(lèi)端礼,并通過(guò)屬性name禽笑,說(shuō)明了輸入欄name的類(lèi)型為字符串,最大長(zhǎng)度為200蛤奥。
在investigate()函數(shù)中佳镜,我們根據(jù)POST,直接創(chuàng)立form對(duì)象凡桥。該對(duì)象可以直接判斷輸入是否有效蟀伸,并對(duì)輸入進(jìn)行預(yù)處理∶骞簦空白輸入被視為無(wú)效啊掏。
后面,我們?cè)俅蝿?chuàng)建一個(gè)空的form對(duì)象衰猛,并將它交給模板顯示迟蜜。
在模板investigate.html中,我們可以直接顯示form對(duì)象:
# <form action="/west/investigate/" method="post">
# {% csrf_token %}
# {{ form.as_p }}
# <input type="submit" value="Submit">
# </form>
# {% for person in staff %}
# <p>{{ person }}</p>
# {% endfor %}