Django newforms

由于前两天被 django forms 中的 manipulator 弄怕了,觉得这个东西比较难用。在 python-chinese 邮件列表中提问后,按照建议,我开始学习 newforms 了。本文是一些摘要。

newforms 的第一个好处是不必和 model 耦合,专门负责 html 的显示和验证。并且调试相对简便,我们随时可以通过 print 来输出其将要 render 的 html.

如何定义 Form 类

Form 类可以分为两种:绑定数据的和不绑定数据的。对于绑定数据的 Form, 可以进行验证(validate).
而 Form 可以有多种办法来创建。可以通过子类化的方式完全定制(继承 django.newforms.Form);也可以用一些帮助方法,直接返回一个定制的 Form 实例。比如:

if  id  is  None:
    EntryForm 
=  forms.models.form_for_model(Entry)
else :
    entry 
=  Entry.objects.get(id = id)
    EntryForm 
=  forms.models.form_for_instance(entry)

这段代码演示了从模型或模型类的实例直接创建相应 Form 的用法。对于简单的情形这样做应该是没问题的。

完全定制的做法:

>>>   class  PersonForm(Form):
     first_name 
=  CharField()
     last_name 
=  CharField()
>>>   class  InstrumentForm(Form):
     instrument 
=  CharField()
>>>   class  BeatleForm(PersonForm, InstrumentForm):
     haircut_type 
=  CharField()
>>>  b  =  BeatleForm(auto_id = False)
>>>   print  b.as_ul()
< li > First name:  < input type = " text "  name = " first_name "   /></ li >
< li > Last name:  < input type = " text "  name = " last_name "   /></ li >
< li > Instrument:  < input type = " text "  name = " instrument "   /></ li >
< li > Haircut type:  < input type = " text "  name = " haircut_type "   /></ li >

这个例子表明在子类化 Form 的时候,甚至可以用多继承。

Form 的实例化

Form 的构造器中可以传递一个字典,代表其中包含的数据,这种情况下 Form 被称之为是“绑定的”;而如果不传递任何数据,则称为“非绑定的”。

#  绑定数据的 Form
=  SomeForm({ " email " " test@test.com " " username " " abc " })
#  非绑定的 Form
f2  =  SomeForm()

通过 f.is_bound 可以判断一个 form 是否绑定了数据。需要注意的是,数据目前被设计为不可变的,即一旦传递给 f 对象的构造器,则没有办法改变它。

Form 的输出形式

Form 的输出形式,默认的有如下几种:

print  f.as_p()  #  每个字段输出为一个 <p/> 标签
print  f.as_table()  #  表格,这是默认情形
print  f.as_ul()  #  <ul/>
print  f  #  和 print f.as_table() 等效

验证数据

直接用 f.is_valid() 即可。这个操作对非绑定的 Form 无意义。
如果存在错误,则 f.errors 中包含了各字段的错误信息。该属性是一个字典,以 field 名称为 key.
如果你直接访问 f.errors,并不需要先调用 f.is_valid(),Django 会自动调用它的。

newforms 设计中的另一个好处是,通过 f.clean_data 可以获取验证后的数据。这些数据的格式是统一的形式,不管他们输入时是什么样的。比如对于日期字段,通过这个属性,最终得到的都是 python 的 datetime.date 类型。

另外一个重要的话题是关于 Fields,这一块比较琐碎,具体的描述可以看文档。值得记一下的几个要点:

1. Field 的 clean() 方法,用于验证数据;
2. Field 默认是必填的;(对应于构造器中的 required 参数)
3. Field 可以指定用于输出 HTML 的具体 widget(小控件)。
    比如我们要把一个字段显示为富文本控件,就可以创建自定义的 Widget 来实现。


代码示例

摘自: http://code.pui.ch/2007/01/07/using-djangos-newforms/
def  add_edit_entry(request, id = None):
    
if  id  is  None:
        EntryForm 
=  forms.models.form_for_model(Entry)
    
else :
        entry 
=  Entry.objects.get(id = id)
        EntryForm 
=  forms.models.form_for_instance(entry)
    EntryForm.fields[
' detail ' ].widget  =  TinyMCE()
    
if  request.method  ==   ' POST ' :
        form 
=  EntryForm(request.POST)
        
if  form.is_valid():
            entry 
=  form.save(commit = False)
            
if  id  is  None:
                entry.owner 
=  request.user
            entry.save()
            
return  HttpResponseRedirect( " / " )
    
else :
        form 
=  EntryForm()
    t 
=  loader.get_template( ' add_entry.html ' )
    c 
=  Context({
        
' form ' : form,
        
' html_head ' ' <script src="/media/tiny_mce/tiny_mce_src.js" type="text/javascript"></script> '
    })
    
return  HttpResponse(t.render(c))

add_entry.html
{% extends "base.html" %}

{% block content %}
< form  action ="."  method ="post" >
  
< table  class ="form" >
    {{ form }}
  
</ table >
  
< input  type ="submit"  value ="speichern"   />
</ form >
{% endblock %}

以上这段代码是个简单的范本,其中没有用到自定义 Form. 因此更灵活的用法还需要我们继续去发掘。

参考资源

http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py
http://code.pui.ch/2007/01/07/using-djangos-newforms/
http://www.mikecantelon.com/?q=node/22

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值