I solved this without modifying Crispy Forms, by creating a new field type that renders a formset:
from crispy_forms.layout import LayoutObject, TEMPLATE_PACK
class Formset(LayoutObject):
"""
Layout object. It renders an entire formset, as though it were a Field.
Example::
Formset("attached_files_formset")
"""
template = "%s/formset.html" % TEMPLATE_PACK
def __init__(self, formset_name_in_context, template=None):
self.formset_name_in_context = formset_name_in_context
# crispy_forms/layout.py:302 requires us to have a fields property
self.fields = []
# Overrides class variable with an instance level variable
if template:
self.template = template
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
formset = context[self.formset_name_in_context]
return render_to_string(self.template, Context({'wrapper': self,
'formset': formset}))
It needs a template to render the formset, which gives you control over exactly how it's rendered:
{% load crispy_forms_tags %}
<div class="formset">
{% crispy formset %}
<input type="button" name="add" value="Add another" />
</div>
You can use it to embed a formset in your layouts just like any other Crispy layout element:
self.helper.layout = Layout(
MultiField(
"Education",
Formset('education'),
),
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…