aquí es lo que solía para un caso similar (un conjunto variable de fieldsets, cada uno que contiene un conjunto variable de campos).
Usé la función type()
para construir mi clase de formulario, y BetterBaseForm
clase de django-form-utils.
def makeFurnitureForm():
"""makeFurnitureForm() function will generate a form with
QuantityFurnitureFields."""
furnitures = Furniture.objects.all()
fieldsets = {}
fields = {}
for obj in furnitures:
# I used a custom Form Field, but you can use whatever you want.
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)
# Here I use a double list comprehension to define my fieldsets
# and the fields within.
# First item of each tuple is the fieldset name.
# Second item of each tuple is a dictionnary containing :
# -The names of the fields. (I used a list comprehension for this)
# -The legend of the fieldset.
# You also can add other meta attributes, like "description" or "classes",
# see the documentation for further informations.
# I added an example of output to show what the dic variable
# I create may look like.
dic = [(name, {"fields": [field.name for field in fieldsets[name]], "legend" : name})
for name in fieldsets.keys()]
print(dic)
# Here I return a class object that is my form class.
# It inherits from both forms.BaseForm and forms_utils.forms.BetterBaseForm.
return (type("FurnitureForm",
(forms.BaseForm, form_utils.forms.BetterBaseForm,),
{"_fieldsets" : dic, "base_fields" : fields,
"_fieldset_collection" : None, '_row_attrs' : {}}))
Aquí es un ejemplo de cómo dic
puede verse como:
[('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']})]
he usado en lugar de BetterBaseForm
BetterForm
por la misma razón this article sugiere utilizar BaseForm
en lugar de Form
.
Este artículo es interesante aunque sea antiguo, y explica cómo hacer formas dinámicas (con un conjunto variable de campos). También le da otras formas de lograr formas dinámicas.
Sin embargo, no explica cómo hacerlo con fieldsets, pero me inspiró para encontrar cómo hacerlo, y el principio sigue siendo el mismo.
se utiliza en un punto de vista es bastante simple:
return (render(request,'main/form-template.html', {"form" : (makeFurnitureForm())()}))
y en una plantilla:
<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>
¿No sería mejor usar [Formsets] (http: //docs.djangoproject .com/es/dev/topics/forms/formsets /) en lugar de conjuntos de campo? Una clase de formulario personalizada para una pregunta (con un atributo 'prompt'), luego carga los datos de la pregunta usando el argumento de la palabra clave' 'initial'] (http://docs.djangoproject.com/en/dev/topics/forms/formsets/# using-initial-data-with-a-formset)? –
Formsets no funcionan. al menos no el formset_factory dado. Tengo que poder proporcionar algunos parámetros a los constructores de campo reales para cada formulario en el formset - la etiqueta/solicitud para el campo de valor, y la lista de unidades para el campo choice. –