Python's Archiver

為方便港臺同胞閱覽,Python中國特別推出簡繁體內容轉換功能

xieaotian 发表于 2008-11-11 22:34

[django]newforms两种方式示例

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

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.