Question

I'm using the following code to wrap all the form fields of a form in a formset together in a div with django crispy forms:

class OperatorForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(OperatorForm, self).__init__(*args, **kwargs):
            self.helper = FormHelper(self)
            self.helper.form_tag = False
            self.helper.all().wrap_together(Div, css_class="operator-form")
            self.helper.render_unmentioned_fields = True

    class Meta:
        model = Operator
        fields = tuple(fields_list)

Instantiating FormHelper with 'self' autogenerates the layout without having to specify all fields. I need this because my fields are dynamically generated. The problem is that the DELETE and ORDER fields are not added to the layout. So I set render_unmentioned_fields to True. With this setting these two fields at least show up in the form, but are not wrapped with the rest of the fields in the div.

I know I can manually iterate over the forms in a formset and wrap them with a div, which is what I've been doing up to now, but this requires manual handling of the non form errors of the formset, which is usually done automatically by crispy.

EDIT: Updated code as requested. This entire class is actually wrapped in a factory method that populates fields_list, so that I can dynamically include only certain fields. ORDER and DELETE are left out on purpose. They are automatically detected (including them results in an error) and display in the form, they are simply not wrapped in the div.

Was it helpful?

Solution

As Brian Dant suggested, ORDER and DELETE should be added manually if they are to be included in the Layout. My problem was that I also passed them to the Meta class's `fields'.

class _OperatorForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(_OperatorForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_tag = False
        self.helper.layout.extend(['ORDER', 'DELETE'])
        self.helper.all().wrap_together(Div, css_class="operator-form")

    class Meta:
        model = ApplicationOperator
        fields = tuple(fields_list)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top