It is all very simple. I have this form:
class add_basketForm(forms.Form):
def __init__(self, selected_subunits, *args, **kwargs):
self.selected_subunits = selected_subunits
super(add_basketForm, self).__init__(*args, **kwargs)
for subunit in self.selected_subunits:
self.fields['su%d' % (subunit['unit__id'])] = forms.IntegerField()
The number of subunits are unknown. I would like to use something like this (you get the idea):
{% for unit in selected_subunits %}
{{ form.su%s }} % (unit.unit__id)
{% endfor %}
But of course that doesn't work. My question is how do I reference those formfields in Django template language?
In order to access the BoundField instances for your dynamic field instances, which is what gives you access to all of the attributes and methods necessary to render the field, you need to access the field objects using the form of form.fieldname
rather than form.fields[fieldname]
Here's a potential refactoring of your form class:
class add_basketForm(forms.Form):
def __init__(self, selected_subunits, *args, **kwargs):
super(add_basketForm, self).__init__(*args, **kwargs)
for subunit in self.selected_subunits:
self.fields['su%d' % (subunit['unit__id'])] = forms.IntegerField()
def su_fields(self):
for name in self.fields:
if name.startswith('su'):
yield(self[name])
Then in your template, you should be able to iterate over the fields as you would normally expect by accessing form.su_fields
:
{% for su_field in form.su_fields %}
....
{% endfor %}
(I had been struggling with this same problem for several hours. Thanks to this answer from Carl Meyer and this article on dynamic form generation from Jacob Kaplan-Moss for pointing me in the right directions.)
Group those fields in an additional list and then simply iterate over this list.
In __init__
:
self.subunit_list = []
for subunit in self.selected_subunits:
field = forms.IntegerField()
self.fields['su%d' % (subunit['unit__id'])] = field
self.subunit_list.append(field)
In template:
{% for field in form.subunit_list %}
...
{% endfor %}
To correct gruszczy's answer, this code worked for me:
In __init__
of your form:
self.subunit_list = []
for subunit in self.selected_subunits:
field = forms.IntegerField()
self.fields['su%d' % (subunit['unit__id'])] = field
self.subunit_list.append(self['su%d' % (subunit['unit__id'])])
In your template:
{% for field in form.subunit_list %}
<!-- show form field (inputbox) -->
{{ field }}
{% endfor %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With