2009-01-04 94 views
18

是否有可能使用django表单可变数量的字段?可以使用Django形式的可变数量输入吗?

的具体应用是这样的:

,因为他们想要的图像上传表单上的用户可上传的图片。一旦图片上传,他们将被带到一个页面,在那里他们可以给图片一个名字和描述。图片的数量取决于用户选择上传的数量。

因此我该如何让django使用可变数量的输入字段(如果需要,可以作为参数传递)来生成表单?

编辑:article mentioned in jeff bauer's answer被写入以来,有些事情发生了变化。

即这行代码,似乎没有工作:

# BAD CODE DO NOT USE!!! 
return type('ContactForm', [forms.BaseForm], { 'base_fields': fields }) 

因此,这里是我想出了...

我用了答案:


from tagging.forms import TagField 
from django import forms 

def make_tagPhotos_form(photoIdList): 
    "Expects a LIST of photo objects (ie. photo_sharing.models.photo)" 

    fields = {} 

    for id in photoIdList: 
     id = str(id) 

     fields[id+'_name'] = forms.CharField() 
     fields[id+'_tags'] = TagField() 
     fields[id+'_description'] = forms.CharField(widget=forms.Textarea) 

    return type('tagPhotos', (forms.BaseForm,), { 'base_fields': fields }) 

注意标记不是django的一部分,但它是免费且非常有用的。检查出来:django-tagging

回答

15

是的,可以在Django中动态创建表单。您甚至可以将动态字段与普通字段混合匹配。

class EligibilityForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(EligibilityForm, self).__init__(*args, **kwargs) 
     # dynamic fields here ... 
     self.fields['plan_id'] = CharField() 
    # normal fields here ... 
    date_requested = DateField() 

对于这种技术的更好的阐述,见詹姆斯贝内特的文章:所以你想一个动态的形式?

http://www.b-list.org/weblog/2008/nov/09/dynamic-forms/

7

如果运行

python manage.py shell 

和类型:

from app.forms import PictureForm 
p = PictureForm() 
p.fields 
type(p.fields) 

你会看到p.fields是SortedDict。你只需要插入一个新的字段。类似于

p.fields.insert(len(p.fields)-2, 'fieldname', Field()) 

在这种情况下,它会在最后一个字段之前插入一个新字段。你现在应该适应你的代码。

其他的替代方法是在你的模板中创建一个for/while循环,并在HTML中完成表单,但是django由于某种原因形成了摇滚,对吧?

+0

几乎放弃你接受的答案,杰夫的只是一点点清晰的(链接帮助了很多) – Jiaaro 2009-01-05 18:30:43

7

选其一多种形式(django.forms.Form未标记)

class Foo(forms.Form): 
    field = forms.Charfield() 

forms = [Foo(prefix=i) for i in xrange(x)] 

或添加多个字段来动态地使用self.fields形式。

class Bar(forms.Form): 
    def __init__(self, fields, *args, **kwargs): 
     super(Bar, self).__init__(*args, **kwargs) 
     for i in xrange(fields): 
      self.fields['my_field_%i' % i] = forms.Charfield() 
相关问题