form = ProductForm(request.POST or None):python or 含義:如果第1個爲真,返回第1個,否則返回第2個
def search(request):
**errors = []**
if 'q' in request.GET:
q = request.GET['q']
if not q:
**errors.append('Enter a search term.')**
elif len(q) > 20:
**errors.append('Please enter at most 20 characters.'
else:
books = Book.objects.filter(title__icontains=q)
return render_to_response('search_results.html',
{'books': books, 'query': q})
return render_to_response('search_form.html',
{**'errors': errors** })
from django.core.mail import send_mail
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def contact(request):
errors = []
if request.method == 'POST':
if not request.POST.get('subject', ''):
errors.append('Enter a subject.')
if not request.POST.get('message', ''):
errors.append('Enter a message.')
if request.POST.get('email') and '@' not in request.POST['email']:
errors.append('Enter a valid e‐mail address.')
if not errors:
send_mail(
request.POST['subject'],
request.POST['message'],
request.POST.get('email', '[email protected]'),
['[email protected]'],
)
return HttpResponseRedirect('/contact/thanks/')
return render_to_response('contact_form.html',
{'errors': errors})
當郵件發送成功之後,我們使用HttpResponseRedirect對象將網頁重定向至一個包含成功信息的頁面。 包
含成功信息的頁面這裏留給讀者去編寫(很簡單 一個視圖/URL映射/一份模板即可),但是我們要解釋一
下爲何重定向至新的頁面,而不是在模板中直接調用render_to_response()來輸出。
原因就是: 若用戶刷新一個包含POST表單的頁面,那麼請求將會重新發送造成重複。 這通常會造成非期望
的結果,比如說重複的數據庫記錄;在我們的例子中,將導致發送兩封同樣的郵件。 如果用戶在POST表單
之後被重定向至另外的頁面,就不會造成重複的請求了。
我們應每次都給成功的POST請求做重定向。 這就是web開發的最佳實踐。
1)Python解釋器裏面看看這個類做了些什麼。 它做的第一件事是將自己顯示成HTML:
>>> from contact.forms import ContactForm
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" id="id_
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email"
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_
Form對象做的第二件事是校驗數據。 爲了校驗數據,我們創建一個新的對Form象,並且傳入一個與定義匹配的
字典類型數據:
>>> f = ContactForm({'subject': 'Hello', 'email': '[email protected]', 'message': 'Nice site!'})
一旦你對一個Form實體賦值,你就得到了一個綁定form:
>>> f.is_bound
obook.py3k.cn/2.0/chapter07/12/182010-5-5第七章:表單
True
調用任何綁定form的is_valid()方法,就可以知道它的數據是否合法。 我們已經爲每個字段傳入了值,因此整
個Form是合法的:
>>> f.is_valid()
True
每一個邦定Form實體都有一個errors屬性,它爲你提供了一個字段與錯誤消息相映射的字典表。
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.errors
{'message': [u'This field is required.']}
最終,如果一個Form實體的數據是合法的,它就會有一個可用的cleaned_data屬性。 這是一個包含乾淨的提交
數據的字典。 Django的form框架不但校驗數據,它還會把它們轉換成相應的Python類型數據,這叫做清理數
據。
>>> f = ContactForm({subject': Hello, email: [email protected], message: Nice site!})
>>> f.is_valid()
True
>>> f.cleaned_data
{message': uNice site!, email: [email protected], subject: uHello}
在視圖中使用Form對象
from django.shortcuts import render_to_response
from mysite.contact.forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
cd['subject'],
cd['message'],
cd.get('email', '[email protected]'),
['[email protected]'],
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm()
return render_to_response('contact_form.html', {'form': form})
# contact_form.html
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Submit">
</form>
</body>
</html>
看看,我們能移除這麼多不整齊的代碼! Django的forms框架處理HTML顯示、數據校驗、數據清理和表單錯
誤重現。
1 改變字段顯示
你可能首先注意到:當你在本地顯示這個表單的時,message字段被顯示成`` input type=”text”`` ,而它應該
被顯示成<`` textarea`` >。我們可以通過設置* widget* 來修改它:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField(required=False)
message = forms.CharField(**widget=forms.Textarea** )
obook.py3k.cn/2.0/chapter07/14/182010-5-5第七章:表單
forms框架把每一個字段的顯示邏輯分離到一組部件(widget)中。 每一個字段類型都擁有一個默認的部件,
我們也可以容易地替換掉默認的部件,或者提供一個自定義的部件。
考慮一下Field類表現* 校驗邏輯* ,而部件表現* 顯示邏輯* 。
2 設置最大長度
一個最經常使用的校驗要求是檢查字段長度。 另外,我們應該改進ContactForm,使subject限制在100個字符
以內。 爲此,僅需爲CharField提供max_length參數,像這樣:
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(**max_length=100** )
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
選項min_length參數同樣可用。
3 設置初始值
讓我們再改進一下這個表單:爲字subject段添加* 初始值* : "I love your site!" (一點建議,但沒壞處。
)爲此,我們可以在創建Form實體時,使用initial參數:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
send_mail(
cd['subject'],
cd['message'],
cd.get('email', `'[email protected]`_'),
[`'[email protected]`_'],
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm(
**initial={'subject': 'I love your site!'}**
)
return render_to_response('contact_form.html', {'form': form})
現在,subject字段將被那個句子填充。
請注意,傳入* 初始值* 數據和傳入數據以* 綁定* 表單是有區別的。 最大的區別是,如果僅傳入* 初始值* 數
據,表單是unbound的,那意味着它沒有錯誤消息。
4 自定義校驗規則
假設我們已經發布了反饋頁面了,email已經開始源源不斷地涌入了。 這裏有一個問題: 一些提交的消息只有
一兩個字,我們無法得知詳細的信息。 所以我們決定增加一條新的校驗: 來點專業精神,最起碼寫四個字,拜
託。
我們有很多的方法把我們的自定義校驗掛在Django的form上。 如果我們的規則會被一次又一次的使用,我們
可以創建一個自定義的字段類型。 大多數的自定義校驗都是一次性的,可以直接綁定到form類.
djangobook.py3k.cn/2.0/chapter07/15/182010-5-5第七章:表單
我們希望`` message`` 字段有一個額外的校驗,我們增加一個`` clean_message()`` 方法到`` Form`` 類:
1from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
Django的form系統自動尋找匹配的函數方法,該方法名稱以clean_開頭,並以字段名稱結束。 如果有這樣
方法,它將在校驗時被調用。
特別地,clean_message()方法將在指定字段的默認校驗邏輯執行* 之後* 被調用。(本例中,在必
填CharField這個校驗邏輯之後。)因爲字段數據已經被部分處理,所以它被從self.cleaned_data中提取出來
了。同樣,我們不必擔心數據是否爲空,因爲它已經被校驗過了。
我們簡單地使用了len()和split()的組合來計算單詞的數量。 如果用戶輸入字數不足,我們拋出一
個forms.ValidationError型異常。這個異常的描述會被作爲錯誤列表中的一項顯示給用戶。
在函數的末尾顯式地返回字段的值非常重要。 我們可以在我們自定義的校驗方法中修改它的值(或者把它轉換
成另一種Python類型)。 如果我們忘記了這一步,None值就會返回,原始的數據就丟失掉了。
5 指定標籤
HTML表單中自動生成的標籤默認是按照規則生成的:用空格代替下劃線,首字母大寫。如email的標籤
是"Email" 。(好像在哪聽到過? 是的,同樣的邏輯被用於模塊(model)中字段的verbose_name值。 我們在
第五章談到過。)
像在模塊中做過的那樣,我們同樣可以自定義字段的標籤。 僅需使用label,像這樣:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False, **label='Your e‐mail address'** )
message = forms.CharField(widget=forms.Textarea)
6 定製Form設計
在上面的`` contact_form.html`` 模板中我們使用`` {{form.as_table}}`` 顯示錶單,不過我們可以使用其他更精
確控制表單顯示的方法。
修改form的顯示的最快捷的方式是使用CSS。 尤其是錯誤列表,可以增強視覺效果。自動生成的錯誤列表精確
的使用`` <ul class=”errorlist”>``,這樣,我們就可以針對它們使用CSS。 下面的CSS讓錯誤更加醒目了:
<style type="text/css">
ul.errorlist {
margin: 0;
padding: 0;
}
.errorlist li {
background‐color: red;
display: block;
font‐size: 10px;
margin: 0 0 3px;
padding: 4px 5px;
}
</style>
雖然,自動生成HTML是很方便的,但是在某些時候,你會想覆蓋默認的顯示。 {{form.as_table}}和其它的方
法在開發的時候是一個快捷的方式,form的顯示方式也可以在form中被方便地重寫。
每一個字段部件(<input type=”text”>, <select>, <textarea>, 或者類似)都可以通過訪問{{form.字段名}}進
行單獨的渲染。
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post">
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
<label for="id_email">Your e‐mail address:</label>
{{ form.email }}
</div>
<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
{{ form.message }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
{{ form.message.errors }} 會在 <ul class="errorlist"> 裏面顯示,如果字段是合法的,或者form沒有被綁
定,就顯示一個空字符串。 我們還可以把 form.message.errors 當作一個布爾值或者當它是list在上面做迭代,
例如:
<div class="field{% if form.message.errors %} errors{% endif %}">
{% if form.message.errors %}
<ul>
{% for error in form.message.errors %}
<li><strong>{{ error }}</strong></li>
{% endfor %}
</ul>
{% endif %}
<label for="id_message">Message:</label>
Copyright 2006 Adrian Holovaty and Jacob Kaplan-Moss.
This work is licensed under the GNU Free Document License.
Hosting graciously provided by
Chinese translate hosting by py3k.cn.
Document License`_.
{{ form.message }}
</div>
在校驗失敗的情況下, 這段代碼會在包含錯誤字段的div的class屬性中增加一個”errors”,在一個有序列表中
顯示錯誤信息。
django book2 表單學習筆記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
Python Mako模版之頁面繼承
追_梦_者
2020-02-21 09:23:43
騰訊雲centos7.2安裝MySQL5.5
qq_33893206
2018-09-03 17:19:34
Django book2 模型 學習筆記
风之诺
2018-08-29 04:58:38
djanjo book2 學習筆記 (會話 用戶 和註冊)
风之诺
2018-08-29 04:58:38
djanjo中render,render_to_response 兩者的區別
mypenny
2018-08-26 03:43:58