dynamic forms with django

Today I started learning how to write web forms in django. My quest was to write a simple search form where I could specify multiple criteria . Django is a very nice and flexible framework written in python and it is also reasonably well documented.

I don’t feel writing much today. this is the code :

The tricky part was to understand how to re-display the view and to add a new field. This is easily accomplished in django using the formset class that allows to put display together more then one form. In this case the logic is simple. First we display an empty form with two submit buttons, Add and Search. Search brings the obvious result. Add gets the data that was submitted, validates it and re-display the form with an additional field. Note also that the default validation functions are used transparently to validate the input of each sub-form.

views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response
from cudfdep.depo.forms import SearchField
from django.forms.formsets import formset_factory
from django.http import Http404

def search(request):
    SearchFormSet = formset_factory(SearchField)
    data = {'formset': SearchFormSet(), 'debug' : 'default'}
    if request.method == 'POST':
        formset = SearchFormSet(request.POST)
        if formset.is_valid() :
            if request.POST.get('form-submit') == 'Add':
                data = {'formset': SearchFormSet(initial=formset.cleaned_data), 'debug' : 'add'}
            elif (request.POST.get('form-submit') == 'Search' ):
                data = {'formset': SearchFormSet(), 'debug' : 'result' }
            else :
                raise Http404('Invalid request')
        else :
            data = {'formset': formset, 'debug' : 'not valid'}

    return render_to_response('search_form.html', data)

The forms file describes the form logic to be displayed.

forms.py

from django import forms

class SearchField(forms.Form):
    date = forms.DateTimeField(label='date', widget=forms.DateTimeInput)
    arch = forms.ChoiceField([(0,'i386'),(1,'amd64')], widget=forms.Select,initial=0)
    release = forms.ChoiceField([(0,'etch'),(1,'lenny'),(2,'sid'),(3,'squeeze')],widget=forms.Select,initial=0)

This is the template :

search_form.html

<html>
<head>
    <title>Search Form</title>
</head>
<body>
    <form action="" method="post">
      {{ formset.management_form }}
      <table>
          {% for form in formset.forms %}
          {{ form.as_table }}
          {% endfor %}
      </table>
      <input name='form-submit' type="submit" value="Add">
      <input name='form-submit' type="submit" value="Search">
    </form>
    {% if debug %}
        <p style="color: red;">{{ debug }}</p>
    {% endif %}
</body>
</html>