Created
November 18, 2021 16:44
-
-
Save maqnius/37652a3f9f08d0e41e6d958166113544 to your computer and use it in GitHub Desktop.
django crispy forms: Nesting a formset within a form
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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'), | |
| ), | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| {% load crispy_forms_tags %} | |
| <div class="formset"> | |
| {% if helper is not None %} | |
| {% crispy formset helper %} | |
| {% else %} | |
| {{ formset|crispy }} | |
| {% endif %} | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| ========================================================================= | |
| 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