Making a Django form class with a dynamic number of fields Making a Django form class with a dynamic number of fields python python

Making a Django form class with a dynamic number of fields


Jacob Kaplan-Moss has an extensive writeup on dynamic form fields:http://jacobian.org/writing/dynamic-form-generation/

Essentially, you add more items to the form's self.fields dictionary during instantiation.


Here's another option: how about a formset?Since your fields are all the same, that's precisely what formsets are used for.

The django admin uses FormSets + a bit of javascript to add arbitrary length inlines.

class ColorForm(forms.Form):    color = forms.ChoiceField(choices=(('blue', 'Blue'), ('red', 'Red')))ColorFormSet = formset_factory(ColorForm, extra=0) # we'll dynamically create the elements, no need for any formsdef myview(request):    if request.method == "POST":        formset = ColorFormSet(request.POST)        for form in formset.forms:            print "You've picked {0}".format(form.cleaned_data['color'])    else:        formset = ColorFormSet()    return render(request, 'template', {'formset': formset}))

JavaScript

    <script>        $(function() {            // this is on click event just to demo.            // You would probably run this at page load or quantity change.            $("#generate_forms").click(function() {                // update total form count                quantity = $("[name=quantity]").val();                $("[name=form-TOTAL_FORMS]").val(quantity);                  // copy the template and replace prefixes with the correct index                for (i=0;i<quantity;i++) {                    // Note: Must use global replace here                    html = $("#form_template").clone().html().replace(/__prefix_/g', i);                    $("#forms").append(html);                };            })        })    </script>

Template

    <form method="post">        {{ formset.management_form }}        <div style="display:none;" id="form_template">            {{ formset.empty_form.as_p }}        </div><!-- stores empty form for javascript -->        <div id="forms"></div><!-- where the generated forms go -->    </form>    <input type="text" name="quantity" value="6" />    <input type="submit" id="generate_forms" value="Generate Forms" />


you can do it like

def __init__(self, n,  *args, **kwargs):  super(your_form, self).__init__(*args, **kwargs)  for i in range(0, n):    self.fields["field_name %d" % i] = forms.CharField()

and when you create form instance, you just do

forms = your_form(n)

it's just the basic idea, you can change the code to whatever your want. :D