Combining multiple forms in django

Conveniently, a django.forms.Form object is little more than a collection of fields, meaning that you can concatenate outputs to construct a single form in html, like so:

<form action="" method="POST">
    {{ form1.as_ul }}
    {{ form2.as_ul }}
    <input type="submit" />
</form>

Using a couple of generator expressions, we can combine large or unknown numbers of Form objects with some fairly compact code. Say for instance we want an html form constructed out of a whole bunch of ModelForm objects. Our view for creating/editing this form could look something like this:

def my_view(request, *args, **kwargs):
    # First, retrieve/construct ModelForm subclasses and 
    # instances somehow:
    magic()
    
    # Next, make a collection of ModelForm subclasses, corresponding 
    # instances and names so that we can iterate over them. We could 
    # also do this programmatically if we didn't know which classes to 
    # use until runtime.
    form_collection = (
        (FirstModelForm, instance_one, name_one),
        (SecondModelForm, instance_two, name_two),
        # ...
        (NthModelForm, instance_n, name_n)
    )

    # Initialise all the forms, in a dictionary that we can later use 
    # as context
    forms = dict(
        ("%s_form" % name, form_class(
            request.POST or None, instance=instance, prefix=name
        ))
        for form_class, instance, name in form_collection
    )

    # if all forms are valid, save all forms
    if all(form.is_valid() for form in forms.values()):
        saved_objs = [form.save() for form in forms.values()]
        return redirect('success-url')

    # if any forms were invalid (or not bound) then render forms
    return render_to_response('my_template', forms)

A variation of this came up in a project, involving dynamically constructed form classes. I was totally impressed by how easy this was to do in django, and how compact the code was thanks to generator expressions and list comprehensions. Just thought I'd share.

Posted Jan. 30, 2010, tagged django forms

“Combining multiple forms in django” is an entry on Ozan Onay's blog

If you enjoyed this, you might also like:

comments