浅析django form(1)


浅析django form(1)

一、django forms

1、特点

django forms是Django的表单处理库。依赖HttpRequest,它具有如下特点:

(1)、快速自动生成HTML表单

(2)、表单数据校验

(3)、错误信息提示

(4)、自动转换为python数据格式

2、探究form类

复制代码
1 #coding=utf-8
2 #forms.py
3 from django import forms
4 
5 class ContactForm(forms.Form):
6     name = forms.CharField(max_length=30)
7     age = forms.IntegerField()
8     email = forms.EmailField(required=False)
9     
复制代码

为每一个将要处理的HTML的`` <Form>`` 定义一个Form类,表单中的每一个字段(域)作为Form类的属性,被展现
成Field类,如果指定非必填可required=False。

(1)、form类所做的就是第一步就是快速生成html代码,如下:

复制代码
#form app下定义forms.py
>>> from form.forms import ContactForm
>>> f = ContactForm
>>> print f
<class 'form.forms.ContactForm'>
#对象
>>> f = ContactForm()
>>> print f
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="tex
t" name="name" maxlength="30" /></td></tr>
<tr><th><label for="id_age">Age:</label></th><td><input type="text" name="age" i
d="id_age" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="em
ail" id="id_email" /></td></tr>
#逐个输出
>>> for obj in f:
...     print obj
...
<input id="id_name" type="text" name="name" maxlength="30" />
<input type="text" name="age" id="id_age" />
<input type="text" name="email" id="id_email" />
#as_table()
>>> print f.as_table()
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="tex
t" name="name" maxlength="30" /></td></tr>
<tr><th><label for="id_age">Age:</label></th><td><input type="text" name="age" i
d="id_age" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" name="em
ail" id="id_email" /></td></tr>
#as_p()
>>> print f.as_p()
<p><label for="id_name">Name:</label> <input id="id_name" type="text" name="name
" maxlength="30" /></p>
<p><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" />
</p>
<p><label for="id_email">Email:</label> <input type="text" name="email" id="id_e
mail" /></p>
#as_ul()
>>> print f.as_ul()
<li><label for="id_name">Name:</label> <input id="id_name" type="text" name="nam
e" maxlength="30" /></li>
<li><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /
></li>
<li><label for="id_email">Email:</label> <input type="text" name="email" id="id_
email" /></li>
#指定输出
>>> print f['name']
<input id="id_name" type="text" name="name" maxlength="30" />
>>>
复制代码

(2)、数据校验与错误信息提示

创建form对象,传入字典类型数据

复制代码
>>>f=ContactForm({'name':'BeginMan','age':100,'email':'x@163.com'})
>>> f.is_bound    #一旦你对一个Form实体赋值,你就得到了一个绑定form
True
>>> f.is_valid()    #调用任何绑定form的is_valid()方法,就可以知道它的数据是否合法
True
>>> f = ContactForm({'name':'BeginMan'})
>>> f.is_valid()
False
#每一个邦定Form实体都有一个errors属性,它提供了一个字段与错误消息相映射的字典表。
>>> f.errors
{'age': [u'This field is required.']}
>>> f.errors['age']
[u'This field is required.']
>>> f['age'].errors
[u'This field is required.']
>>>
复制代码

(3)、转换处理

如果form对象的数据合法,则有cleaned_data属性,一个清理过的提交数据字典。

>>> f.cleaned_data
{'age': 100, 'name': u'BeginMan', 'email': u'x@163.com'}

当然。我们也可以在其生成的html表单中,看到原始效果

复制代码
>>> for obj in f:
...     print obj
...
<input id="id_name" type="text" name="name" value="BeginMan" maxlength="30" />
<input type="text" name="age" value="100" id="id_age" />
<input type="text" name="email" value="x@163.com" id="id_email" />
复制代码

 二、Forms API

参考:https://docs.djangoproject.com/en/1.2/ref/forms/api/

这里列出重点:

1、绑定和未绑定(unbound)表单的区别

Form.is_bound

相同点:

(1)、都是表单实例

(2)、都可以生成html表单代码

(3)、都有相关属性方法

不同点:

(1)、绑定的表单,有绑定的数据,可以验证,rendering the form as HTML with the data displayed in the HTML.

(2)、未绑定的表单,不能验证,为空或默认值。

复制代码
>>> f = ContactForm()#定义未绑定数据的form
>>> f.is_bound
False
>>> data = {'name':'BeginMan','age':22,'email':'xinxinyu2011@163.com'}
>>> boundF = ContactForm(data)#绑定数据
>>> boundF.is_bound
True
>>> print f
<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" typt" name="name" maxlength="30" /></td></tr>
<tr><th><label for="id_age">Age:</label></th><td><input type="text" name="d="id_age" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" naail" id="id_email" /></td></tr>
>>> print boundF
<tr><th><label for="id_name">Name:</label></th>
<td><input id="id_name" typt" name="name" value="BeginMan" maxlength="30" /></td></tr>
<tr><th><label for="id_age">Age:</label></th><td><input type="text" name="alue="22" id="id_age" /></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="text" naail" value="xinxinyu2011@163.com" id="id_email" /></td></tr>
>>>
复制代码

绑定空数据

>>> f=ContactForm({})
>>> f.is_bound
True
>>>

那么如果在post表单数据,则可以这样绑定:

复制代码
 if request.method == 'POST':
        form = ContactForm(request.POST)    #绑定post数据
        ....
 else:
        form = ContactForm()  #如果表单未被提交,则一个未绑定的表单实例被创建
复制代码

2、Form.initial表单初始化。

我认为就是给表单绑定一些数据,用于特定显示或处理。当然这些可有可无,如提示等。如果提供,则是包含表单字段的字典类型。如:

f = ContactForm(initial={'name':'Hi,here','email':'@'})

可以在表单类中初始化,也可以在表单对象中初始化,对于同一个字段的初始化,后者覆盖前者。

复制代码
>>> class CommentForm(forms.Form):
...     name = forms.CharField(initial='class')#initial初始化
...     url = forms.URLField()
...     comment = forms.CharField()
#表单对象中初始化
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
>>> print f
<tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
复制代码

对于这种初始化,在前端显示也有涉及,如:

复制代码
 if request.method == 'POST':
        form = ContactForm(request.POST)    #绑定post数据
        ....
 else:
        #如果表单未被提交,则一个未绑定的表单实例被创建
        form = ContactForm(initial={'name':'Hi,here','email':'@'})  
 return render_to_response('form/form.html',{'form':form})
复制代码

则在页面显示如下,

#template form.html
{{form.as_table}}

注意:

These values are only displayed for unbound forms, and they’re not used as fallback values if a particular value isn’t provided.

3、Form.cleaned_data

始终要明白,当通过一系列的数据来创建表单对象,并验证通过的时候,就要使用cleaned_data属性进行‘清理工作’,所谓的清理就是对给定的数据对应到python类型。

返回的是一组被清理过的字典类型数据。

#对应上面的boundF
>>> boundF.cleaned_data
{'age': 22, 'name': u'BeginMan', 'email': u'xinxinyu2011@163.com'}

 4、自定义样式

这里的样式是自动生成的html代码样式,如各个表单控件的id,错误标签的class等。最初如下:

复制代码
>>> data={'name':'mx'}
>>> f = ContactForm(data)
>>> print f

<tr>
    <th><label for="id_name">Name:</label></th>  <!--默认都带有label-->
  <!--id 都是以'id_'+字段名 组成的-->
    <td><input id="id_name" type="text" name="name" value="mx" maxlength="30" /></td>
</tr>

<tr>
    <th><label for="id_age">Age:</label></th>
    <td>
       <ul class="errorlist">   <!--默认错误标签ul的类是‘errorlist’-->
         <li>This field is required.</li>   <!--显示错误信息-->
       </ul>
       <input type="text" name="age" id="id_age" />
    </td>
</tr>

<tr>
     <th><label for="id_email">Email:</label></th>
     <td><input type="text" name="email" id="id_email" /></td>
</tr>
复制代码

那么现在有3个疑问?:

(1)、能否改变错误类

(2)、能否改变id

(3)、能否去掉label

针对以上三点,一一解答:

(1)、自定义验证样式类:

如果验证不通过,则会输出错误,对应的有“必需”、‘错误’两项,那么就在这两项中做文章。

class ContactForm(Form):
    .......
    error_css_class = 'error'#当提示错误的时候,使用的是error类
    required_css_class = 'required'#当提示必须的时候,使用required类

如:

>>> f = ContactForm(data)
>>> print f.as_table()
<tr class="required"><th><label for="id_name">Name:</label>    ...

By default, forms use django.forms.util.ErrorList to format validation errors.

如果想换一种方式,可以自定义错误显示

复制代码
#forms.py

#自定义错误列表格式
from django.forms.util import ErrorList
class DivErrorList(ErrorList):
    def __unicode__(self):
        return self.as_divs()
    
    def as_divs(self):
        if not self:
            return u''
        return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' %e for e in self])
复制代码
复制代码
>>> from form.forms import ContactForm,DivErrorList #导入
>>> data = {'name':False,'age':'22','email':'sd'}
>>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
>>> print f.as_p()
<p class="required">Name: <input type="text" name="name" value="False" maxlength="30" /></p>
<p class="required">Age: <input type="text" name="age" value="22" /></p>
<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div><!--自定义错误样式-->
<p class="error">Email: <input type="text" name="email" value="sd" /></p>
复制代码

 

(2)、控制label和id

可以使用auto_id变量控制label和id ,auto_id必须为True、False或字符串。

复制代码
>>> f = ContactForm(auto_id=False)#省略了id和label
>>> print f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" maxlength="30" /></td></tr>
......
>>> print f.as_ul()
<li>Name: <input type="text" name="name" maxlength="30" /></li>
.......
>>> print f.as_p()
<p>Name: <input type="text" name="name" maxlength="30" /></p>
......
复制代码

如果auto_id = True 则会自动使用label,且id名称为 它们的字段名

>>> f = ContactForm(auto_id=True)
>>> print f
<tr><th><label for="name">Name:</label></th><td><input id="name" type="text" name="name" maxlength="30" /></td></tr>
。。。。

auto_id使用格式化字符串(%s)

复制代码
>>> f = ContactForm(auto_id='id_for_%s')
>>> print f.as_p()
<p><label for="id_for_name">Name:</label> <input id="id_for_name" type="text" name="name" maxlength="30" /></p>
<p><label for="id_for_age">Age:</label> <input type="text" name="age" id="id_for_age" /></p>
<p><label for="id_for_email">Email:</label> <input type="text" name="email" id="id_for_email" /></p>
复制代码

通过上面我们知道,默认的auto_id使用格式化字符串 auto_id = 'id_%s'

接下来控制Label后缀,通过label_suffix 进行控制

复制代码
>>> f = ContactForm(label_suffix='OK')
>>> print f.as_p()
<p><label for="id_name">NameOK</label> <input id="id_name" type="text" name="name" maxlength="30" /></p>
<p><label for="id_age">AgeOK</label> <input type="text" name="age" id="id_age" /></p>
<p><label for="id_email">EmailOK</label> <input type="text" name="email" id="id_email" /></p>
>>>
复制代码

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值