( , ).
type() Form BetterBaseForm django-form-utils.
def makeFurnitureForm():
"""makeFurnitureForm() function will generate a form with
QuantityFurnitureFields."""
furnitures = Furniture.objects.all()
fieldsets = {}
fields = {}
for obj in furnitures:
field = QuantityFurnitureField(name = obj.name)
fields[obj.name] = field
if not obj.room in fieldsets.keys():
fieldsets[obj.room] = [field,]
else:
fieldsets[obj.room].append(field)
dic = [(name, {"fields": [field.name for field in fieldsets[name]], "legend" : name})
for name in fieldsets.keys()]
print(dic)
return (type("FurnitureForm",
(forms.BaseForm, form_utils.forms.BetterBaseForm,),
{"_fieldsets" : dic, "base_fields" : fields,
"_fieldset_collection" : None, '_row_attrs' : {}}))
, dic:
[('fieldset name 1',
{'legend': 'fieldset legend 2',
'fields' ['field name 1-1']}),
('fieldset name 2',
{'legend': 'fieldset legend 2',
'fields' : ['field 1-1', 'field 1-2']})]
BetterBaseForm BetterForm BaseForm, Form.
This article is interesting, even if it's old, and explains how to make dynamic forms (with a variable set of fields). It also gives other ways to achieve dynamic forms.
This does not explain how to do this using fields, but it inspired me to find how to do it, and the principle remains the same.
Using it in a view is pretty simple:
return (render(request,'main/form-template.html', {"form" : (makeFurnitureForm())()}))
and in the template:
<form method="POST" name="myform" action=".">
{% csrf_token %}
<div>
{% for fieldset in form.fieldsets %}
<fieldset>
<legend>{{ fieldset.legend }}</legend>
{% for field in fieldset %}
<div>
{% include "main/furniturefieldtemplate.html" with field=field %}
</div>
{% endfor %}
</fieldset>
{% endfor %}
</div>
<input type="submit" value="Submit"/>
</form>