newforms是django新的对表单处理功能,查看官方文档:
http://www.djangoproject.com/documentation/newforms/
最近也在看newsform的文章,总结了两种使用的方法,如下所示:
一、根据model自动生成newsform
model:
#
Create your models here.
class
ResType(models.Model):
typename
=
models.CharField(
'
typename
'
,maxlength
=
20
)
class
Admin:
pass
def
__str__
(self):
return
self.typename
class
Resource(models.Model):
title
=
models.CharField(
'
标题
'
,maxlength
=
200
)
content
=
models.TextField(
'
内容
'
,null
=
True, blank
=
True)
resdate
=
models.DateTimeField(
'
发布日期
'
,default
=
DEFAULT_DATE, blank
=
True)
restype
=
models.ForeignKey(ResType)
class
Admin:
list_display
=
(
'
title
'
,)
def
__str__
(self):
return
self.title
view:
from django import newforms as forms
def
public(request, id
=
None):
entry
=
None
if
id
is
None:
EntryForm
=
forms.models.form_for_model(Resource)
else
:
entry
=
Resource.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)
entry.save()
return
HttpResponseRedirect(
"
/
"
)
else
:
form
=
EntryForm()
t
=
loader.get_template(
'
public.html
'
)
c
=
Context({
'
form
'
: form,
'
resource
'
:entry})
return
HttpResponse(t.render(c))
template:
{% load i18n utiltags %}
{% extends "base.html" %}
{% block head%}
{% endblock %}
{% block body %}
<
form
enctype
="multipart/form-data"
action
="/resource/public/{%ifnotequal resource None %}{{resource.id}}/{%endifnotequal%}"
method
="post"
id
="resource_edit"
>
<
div
id
="message"
>
ddd
</
div
>
<
table
>
{{ form }}
</
table
>
<
input
type
="submit"
value
="OK"
>
</
form
>
{% endblock %}
这一种方式主要有如下关键点
1.EntryForm = forms.models.form_for_model(Resource)
生成一个具有Model模型的空的Form,用来显示添加表单
2.EntryForm = forms.models.form_for_instance(entry)
根据一个对象来生成含有该对象数据的Form,用来显示带数据的表单
3.数据保存直接可以通过Post过来的数据创建一Form实例,并调用该实例的save方法
二、自定义Form
有时候通过Model自动创建的Form不适合,譬如:Model中的某些属性我不需要显示在页面上,或数据处理方式比较复杂,这个时候你就需要自定义Form.我们先看看代码:
自定义的Form:
from
django.newforms
import
*
from
apps.resource.models
import
ResType,Tag,Resource
class
ResourceForm(Form):
title
=
CharField(label
=
'
标题
'
,required
=
True)
content
=
CharField(label
=
'
内容
'
,widget
=
Textarea(attrs
=
{
'
rows
'
:
10
,
'
cols
'
:
50
}))
resdate
=
DateField(label
=
'
发布日期
'
)
restype
=
ChoiceField(label
=
'
类别
'
,
choices
=
[(c.id,c.typename)
for
c
in
ResType.objects.all()])
def
__init__
(self, data
=
None, auto_id
=
'
id_%s
'
, prefix
=
None,initial
=
None, instance
=
None):
if
instance
is
not
None:
self.instance
=
instance
new_data
=
{}
new_data[
"
title
"
]
=
instance.title
new_data[
"
content
"
]
=
instance.content
new_data[
"
resdate
"
]
=
instance.resdate
new_data[
"
restype
"
]
=
instance.restype
data
=
new_data
else
:
self.instance
=
None
super(ResourceForm, self).
__init__
(data, auto_id, prefix, initial)
def
save(self, commit
=
True):
if
self.instance
is
not
None:
instance
=
self.instance
else
:
instance
=
Resource()
print
'
test:
'
+
self.clean_data[
"
restype
"
]
instance.title
=
self.clean_data[
"
title
"
]
instance.content
=
self.clean_data[
"
content
"
]
instance.resdate
=
self.clean_data[
"
resdate
"
]
instance.restype
=
ResType.objects.get(id
=
self.clean_data[
"
restype
"
])
if
commit:
instance.save()
return
instance
该自定义Form类中主要有两部分:
1、重写构造函数,主要是传递数据
2、自定义save方法,用来将Form接收的数据进行处理
View:
def
add_entry(request,id
=
None):
if
id
is
not
None:
instance
=
Resource.objects.get(id
=
id)
InstanceForm
=
ResourceForm(instance
=
instance)
else
:
InstanceForm
=
ResourceForm()
if
request.POST:
form1
=
ResourceForm(request.POST)
if
form1.is_valid():
form1.save()
return
HttpResponseRedirect(
'
/
'
)
t
=
loader.get_template(
'
add_entry.html
'
)
c
=
Context({
'
form
'
: InstanceForm
})
return
HttpResponse(t.render(c))
其实View部分和第一种方式很相似的,不同的是Form的创建方式。
Template和以前一样。
只写这么多,作为自己学习的一个记录。
参考资料:
http://code.pui.ch/2007/01/07/using-djangos-newforms/
http://www.djangoproject.com/documentation/newforms/
http://code.djangoproject.com/browser/django/trunk/tests/regressiontests/forms/tests.py