Perhaps something like this:
from django import forms
from django.utils.datastructures import SortedDict
def some_view(request):
data = {}
# Using session to remember the row count for simplicity
if not request.session.get('form_rows', None):
request.session['form_rows'] = 3
# If posted with add row button add one more row
if request.method == 'POST' and request.POST.get('rows', None):
request.session['form_rows'] += 1
data = request.POST
# Create appropriate number of form fields on the fly
fields = SortedDict()
for row in xrange(1, request.session['form_rows']):
fields['value_{0}'.format(row)] = forms.IntegerField()
# Create form class
MyForm = type('MyForm', (forms.BaseForm,), { 'base_fields': fields })
form = MyForm(initial=data)
# When submitted...
if request.method == 'POST' and not request.POST.get('rows', None):
form = MyForm(request.POST)
if form.is_valid():
# do something
return render_to_response('some_template.html', {
'form':form,
}, context_instance=RequestContext(request))
With template:
<form action="" method="post">
{{ form }}
<input type="submit" />
<input type="submit" value='Add' name='rows' />
</form>
This is over simplified but it works.
You could easily modify this example so you can make request using AJAX and just replace old form with new one.