Django 的 Form 真的很好用。

K*K posted @ Fri, 26 Dec 2008 00:44:13 +0800 in 技术 with tags django form , 8363 readers

Django 的 Form 表单真的很好用,完全把以往繁琐的表单操作完全抽象出来,成了一个独立的组件。

该系统的最大特色就是与模板无关,表单元素完全在一个文件里就可以定义好,以后也可以随时扩充,修改,很方便。

为了使用富文本编辑器我还使用了 InPlaceEditor,之所以用它是因为它基于强大的 TinyMCE 编辑器,同时提供了很好的 Ajax 支持,为了使用它我还使用了 django-tinymce,这个东西理论上应该找不到编译好的包,可以用 easy_install 安装(在 Fedora 10 里的 python-setuptools-devel 包里),总之就是怎么方便怎么来啦。 :-)

OK, Let's get start it.

在 app 目录里建立一个 forms 的目录,touch 一个 __init__.py,然后在其中写下 newapp.py 文件,如下内容:

from django import forms
from tinymce.widgets import TinyMCE
 
TYPE_CHOICES = [
    [1, 'Desktop Computer'],
    [2, 'Laptop'],
]
 
class NewProduct(forms.Form):
    name = forms.CharField()
    type_id = forms.ChoiceField(choices=TYPE_CHOICES)
    description = forms.CharField(widget=TinyMCE(mce_attrs={})

添加 View 里某个方法(比如 index)填上:

def index(request):
    from testproject.app.forms.newapp import NewProduct
    new_form = NewProduct()
    return render_to_response('testform.html', { 'new_form' : new_form })

然后改模板,类似如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.01//EN">
<html lang="en">
<head>
    <title>New Product</title>
</head>
<body>
   <h1>New Product</h1>
   <form action="." method="POST">
        {{ new_form.as_table }}
     <p><input type="submit" value="Submit"></p>
    </form>
</body>
</html>

够好用吧?一个 form 定义好以后直接使用 as_table 方法就可以转换成表格。

如果需要更多自定义参数,也可以像访问数据库一样直接调用 form class 里的属性,如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.01//EN">
<html lang="en">
<head>
    <title>New Product</title>
</head>
<body>
   <h1>New Product</h1>
   <form action="." method="POST">
        {{ new_form.name }}
        {{ new_form.type_id }}
        {{ new_form.description }}
     <p><input type="submit" value="Submit"></p>
    </form>
</body>
</html>
 

在 Django 的官方教程里,设计一个 form class 的 ChoiceField 使用的是 Tuple,而我这里经过试验,List 也是可以的,而之所以使用 List,是因为这样可以通过数据库,向 ChoiceField 里添加数据,如:

from django import forms
from tinymce.widgets import TinyMCE
from testproject.app.models import ProductTypes
 
types = ProductTypes.objects.all()
TYPE_CHOICES = []
for type in types:
    TYPE_CHOICES.append([type.id, type.name])
 
class NewProduct(forms.Form):
    name = forms.CharField()
    type_id = forms.ChoiceField(choices=TYPE_CHOICES)
    description = forms.CharField(widget=TinyMCE(mce_attrs={})

嘿嘿,基本到此,还是比较简单的,附带一个我的 TinyMCE 的设置作为结尾好了。

from django import forms
from tinymce.widgets import TinyMCE
from testproject.app.models import ProductTypes
 
types = ProductTypes.objects.all()
TYPE_CHOICES = []
for type in types:
    TYPE_CHOICES.append([type.id, type.name])
 
class NewProduct(forms.Form):
    name = forms.CharField()
    type_id = forms.ChoiceField(choices=TYPE_CHOICES)
    description = forms.CharField(widget=TinyMCE(mce_attrs={'theme' : "advanced",
                                                            'skin' : "o2k7",
                                                            'skin_variant' : "silver",
                                                            'elements' : 'elm3',
                                                            'mode' : 'textareas',
                                                            'theme_advanced_toolbar_location' : "top",
                                                            'theme_advanced_toolbar_align' : "left",
                                                            'theme_advanced_resizing' : 'true',
                                                            'plugins' : "safari,pagebreak,style,layer,save,iespell,xhtmlxtras",
                                                            'theme_advanced_buttons1' : "fontselect,fontsizeselect,|,cut,copy,paste,pastetext,|,bullist,numlist,|,undo,redo,|,link,unlink",
                                                            'theme_advanced_buttons2' : "",
                                                            'theme_advanced_buttons3' : "",
                                                           })

不知道 Rails 或者其它 Web Framework 是否也有比较优秀的特色功能,希望也能有人能够介绍一下。

kid said:
Dec 07, 2009 04:21:48 PM

谢谢你的文章,受益匪浅,加油,我会持续关注的~~~
p.s. 在最后一个例子里,types = ProductTypes.objects.all(),我觉得最好还是先try一下,因为types有值的前提是数据库里有数据,那么万一在数据库里没有数据,它就会报错 :)

Head_small
K*K said:
Dec 12, 2010 08:02:47 PM

@kid: 那个应该不会报错的,因为没有数据会返回一个 [],顶多是没有选项,不过可能需要加上 required = False 才可以提交。。。 -_-#

不过现在都用 forms.ModelChoiceForm() 代替那个功能啦,哈~


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter