Skip to content

Instantly share code, notes, and snippets.

@maqnius
Created November 18, 2021 16:44
Show Gist options
  • Select an option

  • Save maqnius/37652a3f9f08d0e41e6d958166113544 to your computer and use it in GitHub Desktop.

Select an option

Save maqnius/37652a3f9f08d0e41e6d958166113544 to your computer and use it in GitHub Desktop.
django crispy forms: Nesting a formset within a form
# Include formset as crispy forms layout object
self.helper.layout = Layout(
Div(
Field('my_field'),
Formset('my_formset', 'my_formset_helper'),
Button('Add New', 'add-extra-formset-fields'),
),
)
{% load crispy_forms_tags %}
<div class="formset">
{% if helper is not None %}
{% crispy formset helper %}
{% else %}
{{ formset|crispy }}
{% endif %}
</div>
"""
=========================================================================
Disclaimer: This is *almost* a copy of https://stackoverflow.com/a/22053952/11465491.
=========================================================================
Line 49 is changed, and accordingly in the template.
Boolean evaluation of the helper is not reliable since the helper has a `__len__` function defined.
I was not allowed to comment on stack overflow, since I did not have an account.
So I hope, it will save someone some time here.
"""
from crispy_forms.layout import LayoutObject
from django.template.loader import render_to_string
class Formset(LayoutObject):
"""
Renders an entire formset, as though it were a Field.
Accepts the names (as a string) of formset and helper as they
are defined in the context
Examples:
Formset('contact_formset')
Formset('contact_formset', 'contact_formset_helper')
"""
template = "formset.html"
def __init__(self, formset_context_name, helper_context_name=None,
template=None, label=None):
self.formset_context_name = formset_context_name
self.helper_context_name = helper_context_name
# 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, **kwargs):
formset = context.get(self.formset_context_name)
helper = context.get(self.helper_context_name)
# closes form prematurely if this isn't explicitly stated
if helper is not None:
helper.form_tag = False
context.update({'formset': formset, 'helper': helper})
return render_to_string(self.template, context.flatten())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment