23

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
  • I don't get how all that is working together : do you have some code or git repo with a more complet example ? Commented Dec 6, 2020 at 10:26

3 Answers 3

20

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/

Sign up to request clarification or add additional context in comments.

Comments

7

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?

1 Comment

Almost gave you the accepted answer, jeff's was just a little bit clearer (the link helped a lot)
7

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.