Variable number of inputs with Django forms possible?

廉价感情. 提交于 2020-01-11 15:46:35

问题


Is it possible to have a variable number of fields using django forms?

The specific application is this:

A user can upload as many pictures as they want on the image upload form. Once the pictures are uploaded they are taken to a page where they can give the pictures a name and description. The number of pictures will depend on how many the user has chosen to upload.

So how do I get django to generate a form using a variable number of input fields (which could be passed as an argument if necessary)?

edit: a few things have changed since the article mentioned in jeff bauer's answer was written.

Namely this line of code which doesn't seem to work:

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

So here is what I came up with...

The Answer I used:


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 })

note tagging is not part of django, but it is free and very useful. check it out: django-tagging


回答1:


Yes, it's possible to create forms dynamically in Django. You can even mix and match dynamic fields with normal fields.

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()

For a better elaboration of this technique, see James Bennett's article: So you want a dynamic form?

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




回答2:


If you run

python manage.py shell

and type:

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

you'll see that p.fields is a SortedDict. you just have to insert a new field. Something like

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

In this case it would insert before the last field, a new field. You should now adapt to your code.

Other alternative is to make a for/while loop in your template and do the form in HTML, but django forms rock for some reason, right?




回答3:


Use either multiple forms (django.forms.Form not the tag)

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

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

or add multiple fields to the form dynamically using 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()


来源:https://stackoverflow.com/questions/411761/variable-number-of-inputs-with-django-forms-possible

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!