被解放的姜戈04 各取所需


作者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝! 

 

我們在庄園疑雲中講到了服務器上的數據。當時我們是用手動的方式,直接在數據庫插入數據。我們將允許客戶向服務器傳遞數據。

表格是客戶向服務器傳數據的經典方式。我們先會看到傳統的表格提交,然后了解Django的表格對象。

 

“我可不做賠本的買賣”,庄主對姜戈說。

 

html表格

HTTP協議以“請求-回復”的方式工作。客戶發送請求時,可以在請求中附加數據。服務器通過解析請求,就可以獲得客戶傳來的數據,並根據URL來提供特定的服務。 

(http協議的運作方式,詳見http協議

 

HTML文件中可以包含表格標簽。HTML表格的目的是幫助用戶構成HTTP請求,把數據用GET或者POST的方法,傳遞給某一URL地址。下面是一個表格的例子:

<form action="/west/investigate/" method="get">
  <input type="text" name="staff">
  <input type="submit" value="Submit">
</form>

這里的form標簽有兩個屬性。action用於說明URL地址,method說明請求的方法。

表格中還包含有兩個input標簽,即兩個輸入欄目。根據type的不同,第一個為一個文本框,第二個為一個提交按鈕。name為輸入欄的名字。服務器在解析數據時,將以name為索引。

 

我們可以將上面的表格直接存入模板form.html,並在west/views.py中定義一個視圖form()來顯示表格:

from django.shortcuts import render def form(request): return render(request, 'form.html')

設置urls.py,讓對[site]/west/form/的訪問,指向該視圖。

 

最后,我們在west/views.py中定義investigate()來處理該表格提交的數據:

from django.shortcuts import render def investigate(request): rlt = request.GET['staff'] return HttpResponse(rlt)

可以看到,HTTP請求的相關信息,包括請求的方法,提交的數據,都包含在request參數中。

表格是通過GET方法提交的。我們可以通過request.GET['staff'],來獲得name為staff的輸入欄的數據。該數據是一個字符串。investigate()將直接顯示該字符串。

設置urls.py,讓該處理函數對應action的URL([site]/west/investigate/)。

 

當我們訪問http://127.0.0.1:8000/west/form時,將顯示:

提交表格后,頁面將轉到[site]/west/investigate。investigate()讀取字符串后,在頁面上顯示出來。

 

姜戈舔舔嘴唇,“這就是你最好的決斗士?我覺得它們不值。”

 

POST方法

上面我們使用了GET方法。視圖顯示和請求處理分成兩個函數處理。

提交數據時更常用POST方法。我們下面使用該方法,並用一個URL和處理函數,同時顯示視圖和處理請求。

 

先創建模板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。在模板的末尾,我們增加一個rlt記號,為表格處理結果預留位置。

表格后面還有一個{% csrf_token %}的標簽。csrf全稱是Cross Site Request Forgery。這是Django提供的防止偽裝提交請求的功能。POST方法提交的表格,必須有此標簽。

 

在west/views.py中,用investigate()來處理表格:

from django.shortcuts import render from django.core.context_processors import csrf 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 %}對應。我們在這里不深究。

看程序的其它部分。對於該URL,可能有GET或者POST方法。if的語句有POST方法時,額外的處理,即提取表格中的數據到環境變量。

 

最終效果如下:

“哦,是嗎,我可是有更好的貨色”,庄主似乎胸有成竹。 

 

存儲數據

我們還可以讓客戶提交的數據存入數據庫。使用庄園疑雲中創建的模型。我們將客戶提交的字符串存入模型Character。

 

修改west/views.py的investigate():

from django.shortcuts import render from django.core.context_processors import csrf from west.models import Character 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的處理部分,我們調用Character類創建新的對象,並讓該對象的屬性name等於用戶提交的字符串。通過save()方法,我們讓該記錄入庫。

隨后,我們從數據庫中讀出所有的對象,並傳遞給模板。

 

我們還需要修改模板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 %}

我們使用模板語言的for,來顯示所有的記錄。

 

效果如下:

“他只是勉強夠看罷了”,姜戈搖搖頭,德國人也趕快跟着搖搖頭。 

 

表格對象

客戶提交數據后,服務器往往需要對數據做一些處理。比如檢驗數據,看是否符合預期的長度和數據類型。在必要的時候,還需要對數據進行轉換,比如從字符串轉換成整數。這些過程通常都相當的繁瑣。

Django提供的數據對象可以大大簡化這一過程。該對象用於說明表格所預期的數據類型和其它的一些要求。這樣Django在獲得數據后,可以自動根據該表格對象的要求,對數據進行處理。

 

修改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類,並通過屬性name,說明了輸入欄name的類型為字符串,最大長度為200。

在investigate()函數中,我們根據POST,直接創立form對象。該對象可以直接判斷輸入是否有效,並對輸入進行預處理。空白輸入被視為無效。

后面,我們再次創建一個空的form對象,並將它交給模板顯示。

 

在模板investigate.html中,我們可以直接顯示form對象:

<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 %}

如果有多個輸入欄,我們可以用相同的方式直接顯示整個form,而不是加入許多個<input>標簽。

 

效果如下:

 

庄主看看德國人,再看看女仆,臉上露出狡猾的笑容。

 

總結

GET和POST

表格提交

數據庫入庫

表格對象

 

“哈,那個德國人似乎看上了這個黑女仆呢”,庄主心里打着算盤。

 

歡迎閱讀“被解放的姜戈”系列文章。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM