7. Django Form
7.1. Form表單
Django帶有一個form庫,稱為django.forms,這個庫可以處理上一章提到的包括HTML表單的自動生成以及數據驗證。
我們在inventory目錄下增加forms.py文件,與models.py文件類似,專門用來存儲form類。
class ItemForm(forms.Form): ItemCode = forms.CharField() ItemName = forms.CharField() Remark = froms.CharField(required=False)
Form類創建后生成相應字段的html描述格式,Form對象還可以進行校驗數據。我們創建一個新的Form象,初始化為匹配的字典類型數據。這樣我們form的is_valid()方法,來確認表單數據是否合法(符合校驗規則)。
>>> from inventory.forms import ItemForm >>> f=ItemForm({'ItemCode': u'005','ItemName':u'螺絲釘'}) >>> f.is_valid() True >>>
如果初始化參數留空ItemCode或ItemName,整個Form就不合法了,如下:
>>> f=ItemForm({'ItemCode': u'005'})
>>> f.is_valid()
False
>>>
每一個Form實體都有一個errors屬性,它為你提供了所有字段與對應錯誤消息相映射的字典表。
>>> f.errors {'ItemName': [u'This field is required.']} >>>
如果一個Form實體的數據是合法的,它就會有一個可用的cleaned_data屬性。 這是一個包含干凈的提交數據的字典。 Django的form框架不但校驗數據,還會把它們轉換成相應的Python類型數據格式。
>>> f=ItemForm({'ItemCode': u'005','ItemName':u'螺絲釘'})
>>> f.is_valid()
True
>>> f.cleaned_data
{'ItemCode': u'005', 'ItemName': u'\u87ba\u4e1d\u9489', 'Remark': u''}
>>>
7.2. 在視圖中使用Form對象
下示例說明了我們如何用forms框架實現AddItem ():
def AddItem(request): if request.method == 'POST': form = ItemForm(request.POST) if form.is_valid(): cd = form.cleaned_data item = Item() item.ItemCode = cd['ItemCode'] item.ItemName = cd['ItemName'] item.save() return HttpResponseRedirect('/success/') else: form = ItemForm( ) return render_to_response('ItemAdd.html', {'form': form}, context_instance = RequestContext(request))
模板文件ItemAdd.html:
<html> <head> <title>Add Item</title> </head> <body> <h1>Add Item</h1> {% if form.errors %} <p style="color: red;"> Please correct the error{{ form.errors|pluralize }} below. </p> {% endif %} <form action="" method="post"> {% csrf_token %} <table> {{ form.as_table }} </table> <input type="submit" value="Submit"> </form> </body> </html>
代碼看上去是多么的簡潔明了,Django的forms框架處理了HTML顯示、數據校驗、數據清理和表單錯誤重現,讓原來復雜的表單代碼簡潔了很多。下面我們簡要說明forms框架可以做那些事情。
7.2.1. 改變字段顯示
class ItemForm(forms.Form): ItemCode = forms.CharField() ItemName = forms.CharField() Remark = froms.CharField( widget=forms.Textarea )
7.2.2. 設置最大長度
class ItemForm(forms.Form): ItemCode = forms.CharField(max_length=10 ) ItemName = forms.CharField() Remark = froms.CharField( widget=forms.Textarea )
7.2.3. 指定標簽和修改錯誤提示
class ItemForm(forms.Form): ItemCode = forms.CharField( max_length=10 label=u'物料編碼:', error_messages={'required': u'必填項'}, ) ItemName = forms.CharField( label=u'物料名稱:', ) Remark = forms.CharField( required=False,widget=forms.Textarea,label=u'備注:', )
7.2.4. 定制Form設計
我們可以使用CSS更精確控制表單顯示,自動生成的錯誤列表精確的使用 <ul class=”errorlist”>`,我們就可以針對它們使用CSS,下面的CSS讓錯誤更加醒目了:
<style type="text/css"> ul.errorlist { margin: 0; padding: 0; } .errorlist li { background-color: red; color: white; display: block; font-size: 10px; margin: 0 0 3px; padding: 4px 5px; } </style>
7.3. 使用Form類優化入庫表單
下面是我們用Form類優化的入庫單功能,代碼如下:
class InStockBillForm(forms.Form): InStockBillCode = forms.CharField() Operator = forms.CharField() InStockDate = forms.DateTimeField() Amount = forms.IntegerField() Item = forms.ModelChoiceField(queryset = Item.objects.all(), required =True)
注意:Item屬性設置成下拉選擇字段類型,數據集為所有的Item對象。
def AddInStockBill(request): if request.method == 'POST': form = InStockBillForm(request.POST) if form.is_valid(): cd = form.cleaned_data inStockBill = InStockBill() inStockBill.InStockBillCode = cd['InStockBillCode'] inStockBill.InStockDate = cd['InStockDate'] inStockBill.Amount = cd['Amount'] inStockBill.Operator = cd['Operator'] inStockBill.Item = cd['Item'] inStockBill.save() return HttpResponseRedirect('/success/') else: form = InStockBillForm() return render_to_response('InStockAdd.html',{'form': form} ,context_instance = RequestContext(request))
對比前面的AddInStockBill函數代碼,會發現減少了大量的if判斷語句,代碼變得非常簡潔易讀。
模板代碼如下:
<html> <head> <title>Add In Stock Bill</title> </head> <body> <h1>Add In Stock Bill</h1> {% if form.errors %} <p style="color: red;"> Please correct the error{{ form.errors|pluralize }} below. </p> {% endif %} <form action="/AddInStockBill/" method="post" > {% csrf_token %} <table> {{ form.as_table }} </table> <input type="submit" value="Submit"> </form> </body> </html>
瀏覽網頁發現Item的下拉列表沒有出現ItemName的值,在Model里增加__unicode__() 方法可以進行任何處理來返回對一個對象的字符串表示,如對象名稱。
class Item(models.Model): ItemId = models.AutoField(primary_key=True) ItemCode = models.CharField(max_length=50) ItemName = models.CharField(max_length=50) Remark = models.CharField(max_length=200) def__unicode__ (self): return self.ItemName
7.4. 小結
Django表單類確實可以很大程度上簡化表單的開發工作,提高了表單開發效率,其內置了大量的可自定義顯示設置項目等,使用Django Form在某些使用場景會大大的減少工作量。
本章結束時,我們完成了Django的基本使用,更多Django的介紹請請參考《The Django Book》網站。
下一章節我們進入到IDE的使用,介紹2款主流的集成開發環境,而不是總是通過NotePad來進行代碼編輯工作,提高開發的效率。







