We have a crispy form where we want to be able to render different fields in different parts of our forms HTML
template, however we can't find a way of doing this in the Crispy Documentation. Below is some slightly made-up code to illustrate what we are trying to do:
forms.py
helper = FormHelper()
helper.layout_1 = Layout(
Div(
Field('field_1a'),
Field('field_1b')
)
)
helper.layout_2 = Layout(
Div(
Field('field_2a'),
Field('field_2b')
)
)
template.html
<body>
{% crispy form layout_1 %}
<!-- A big bunch of other html -->
{% crispy form layout_2 %}
</body>
Does anyone know a clean way of achieving this?
The approaches we have looked at so far and had to rule out:
choice
fields whose options are determined programmatically.crispy.forms.layout.HTML
object to include the HTML which splits up the two different parts of our layout. However, there is a lot of HTML and it would become difficult to maintain if we embedded this directly into python.Update: This does not work for forms.ModelForm
Try creating two helpers instead of two layouts then explicitly calling your separate helpers. Doing it this way you will have to manually write <form>
tags to enclose both forms in your template but hopefully provides the solution you need.
forms.py
class Form(forms.Form):
field_1a = forms.CharField()
field_1b = forms.CharField()
field_2a = forms.CharField()
field_2b = forms.CharField()
def __init__(self, *args, **kwargs):
super(Form, self).__init__(*args, **kwargs)
self.helper1 = FormHelper()
self.helper1.form_tag = False
self.helper1.layout = Layout(
Div(
Field('field_1a'),
Field('field_1b')
)
)
self.helper2 = FormHelper()
self.helper2.form_tag = False
self.helper2.disable_csrf = True
self.helper2.layout = Layout(
Div(
Field('field_2a'),
Field('field_2b')
)
)
Then in your template:
<body>
<form>
{% crispy form form.helper1 %}
<!-- A big bunch of other html -->
{% crispy form form.helper2 %}
</form>
</body>