Reputation: 3730
I have this view (modified to make it simple to understand):
class MyCreateViewView(CreateView):
model = SomeModel
def get_form(self, form_class=None):
form = super().get_form(form_class)
form.helper = FormHelper(form)
form.fields['additional_field'] = forms.BooleanField(label="Something", required=False)
form.helper.add_input(Submit('submit', "Submit"))
return form
Before adding the FormHelper, the field additional_field
appeared on the template. Now it doesn't. The form in my template is basically one line: {% crispy form %}
.
The django-crispy-forms docs don't show this approach because they are focused on using forms. I'm using the CreateView from Django that builds the form for me, so I don't need a form class.
So far, I noticed that doing form.helper = FormHelper(form)
after programmatically adding the new field solves the problem. But this is not a solution because the view I presented here is a simplified version, and I actually have two views that are doing something similar. So I'm inheriting this class and adding extra fields in the views themselves (meaning FormHelper is already there).
Upvotes: 0
Views: 420
Reputation: 3730
Solution: form.helper = FormHelper()
(notice I'm passing the form as an argument)
Using an IDE led me to this error because the class is FormHelper(form=None)
so having a form
argument that I have, made it easy to fell into this trap. In my opinion, this is not well explained, and you have to dig into the code to understand that passing the form actually builds a Layout (maybe form_for_layout
would be a better naming or simply adding form
to the docstring - I created an issue with this suggestion, and will update this answer if it is implemented):
if form is not None:
self.form = form
self.layout = self.build_default_layout(form)
For someone new to django-crispy-forms (my case), this complicates things because it is actually defining the way the form fields are rendered. This is why adding the FormHelper after adding the field showed no problem (it added the field to the layout!), but doing it the other way around didn't work.
Understanding the problem was in layout led me to other solutions. If you need layout, form.helper.layout = form.helper.build_default_layout(form)
(or del form.helper.layout
) after adding the field also works, but you will lose any changes you made to the Layout.
Upvotes: 0