Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django dynamic Form example

I have a simple requirement for creating a dynamic form in Django - I've seen many examples but they seem to be incomplete, or require more extensive knowledge of Python and Django than I have! None show how the dynamic portion of the example should be called:

This is the form class with Q1 and Q2 - I place a button on the form to add another field called Q3 - and then Q4 if pressed again: I think I got the init function semi correct:

class testform(forms.Form):
    Q1 = forms.CharField()
    Q2 = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(testform,self).__init__(*args,**kwargs)
        self.fields['Q%s'%i] = forms.CharField(label='Q%i' % i)

I want to place a button on the form to add another field called Q3 and then Q4 if pressed again.

  • How do I call the _init_function from the view to add these fields?
  • If I use Javascript to add the field dynamically, how do I call init so that I can correctly validate with Django when I POST the form?
like image 647
afshin Avatar asked May 27 '11 15:05

afshin


1 Answers

To answer your question: Whenever you initialize your form, it calls init(). Ex: form = testform(). That initializes your form. What I would do here is add some javascript to create these new fields. I'm not sure how familiar you are with javascript, but I'm going to assume you can figure this one out on your own.

As for the validation, this can be done in the form. First though, you'll want to tell it that you've added more fields using init().

class TestCharField(forms.CharField):
    def __init__(self, *args, **kwargs):
        super(TestCharField, self).__init__(*args, **kwargs) # Needs * and **
    def clean(self, value):
        super(TestCharField, self).clean(value)
        # Do custom validation in here
        return value

class testform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(testform, self).__init__(args, kwargs)

        # args should be a list with the single QueryDict (GET or POST dict)
        # that you passed it
        for k,v in args[0].items():
            if k.startswith('Q') and k not in self.fields.keys():
                self.fields[k] = TestCharField(initial=v, required=True)

You can name your field whatever you want, it doesn't have to be TestCharField. Just make sure to rename it in both places. This will allow you to make as many fields as you like. Let me know if this doesn't quite work for you.

like image 177
Bryce Siedschlaw Avatar answered Oct 15 '22 22:10

Bryce Siedschlaw