Django dynamic Form example
I have a simple requirement for creating a dynamic form in Django - I've seen ma开发者_Python百科ny 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?
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.
[Edit] This was not the best answer, the answer of Bryce is much better. I took the question literally and gave a solution for 4 fields, where a really dynamic form would have been a much more elegant solution.
Please have a look at Bryce' answer.
I think I'd define the form with all the possible fields and hide/show them with javascript:
class testform(forms.Form)
Q1 = forms.CharField()
Q2 = forms.CharField()
Q3 = forms.CharField()
Q4 = forms.CharField()
HTML:
<table>
{{ testform.as_table }}
</table>
...
<script type="text/javascript">
$(function(){
$('input[name="q3"]').closest('tr').hide();
$('input[name="q4"]').closest('tr').hide();
});
</script>
(using JQuery)
And show the fields using your buttons similarly.
精彩评论