DjangoBook笔记-4
# date: 2010-4-22
# by fatway#gmail.com
23. 表单Form类
对于上面形式的表单,当列多时,后台需要进行繁琐的验证过程,且容易出错
可以使用Django自带的Form类来进行表单的生成和验证
Form类可以放置于任何地址,可以写在views.py中,但习惯上专门写进forms.py中
# file:forms.py
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField(required=False) # 可选项
message = forms.CharField()
显示表单,在shell中测试:
>>> from forms import ContactForm
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_subject">Subject:</label></th><td><input type="text" name="subject" id="id_subject" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="email" id="id_email" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
>>> print f['subject']
<input type="text" name="subject" id="id_subject" />
校验数据
>>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice site!'})
>>> f.is_bound # 是否绑定form
True
>>> f.is_valid() # 数据是否合法
True
>>> f = ContactForm({'subject': 'Hello', 'message': ''})
>>> f.is_valid() # message必填项
False
>>> f['message'].errors # 查看出错信息
[u'This field is required.']
>>> f['subject'].errors
[]
>>> f['email'].errors
[]
>>> f.errors
{'message': [u'This field is required.']}
>>> f.cleaned_data # 清理数据,转换成Python类型
{message: uNice site!, email: uadrian@example.com, subject: uHello}
24. Form在视图中的应用
给一个改进的示例:
# views.py
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', 'noreply@example.com'),
['siteowner@example.com'],
)
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>
一些改进字段显示的方法
改进message显示方式由text改为textarea
class ContactForm(forms.Form):
subject = forms.CharField()
email = forms.EmailField(required=False)
message = forms.CharField(**widget=forms.Textarea** )
设置最大长度
class ContactForm(forms.Form):
subject = forms.CharField(**max_length=100** )
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
指定显示标签
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)
设置初始值
可以在view方法中创建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', `'noreply@example.com`_'),
[`'siteowner@example.com`_'],
)
return HttpResponseRedirect('/contact/thanks/')
else:
form = ContactForm(
**initial={'subject': 'I love your site!'}**
)
return render_to_response('contact_form.html', {'form': form})
25. 自定义Form校验规则
在前面的form设计中,只是在数据提交后进行一些简单的校验,如果想自定义规则
可以使用clean_**方法
如,我们希望message字段有一个额外的检查长度的校验,可以定义clean_message()
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)
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_开头并以字段名结尾的函数,在校验时被调用
在函数的末尾显式地返回字段的值非常重要
可以在自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)
如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了
26. 定制Form设计
在上面的模板显示中,使用{{ form.as_table }}来展示表单
还可以更精确的控制表单显示方式
使用CSS来控制
重写form的显示方式
每个字段部件<input type="text">, <select>, <textarea>等都可以 \
通过访问 {{ from.字段名 }}进行单独的渲染
# contact_from.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">
<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 做迭代
<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>
{{ form.message }}
</div>
# 以上内容既DjangoBook该书的介绍性文章tutorial ,完成了对django的总体认识
# 已经可以本着拿来主义的精神进行实际项目的开展了
# 后面的内容会进行深入和高阶的介绍
-To be Continue-
浙公网安备 33010602011771号