Search code examples
django-formsdjango-crispy-forms

Django Crispy Form With Dynamically Defined Field


I would like to define a Django crispy form with two statically defined fields (name and description) and one dynamically defined field (enum_value). I do it like this:

class DataTypeForm(forms.Form):
    name = forms.CharField()
    description = forms.CharField(widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        self.mode = kwargs.pop('mode')
        super(DataTypeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.wrapper_class = 'row'
        self.helper.label_class = 'col-md-2'
        self.helper.field_class = 'col-md-8'
        self.helper.add_input(Submit('submit', 'Submit'))
        self.fields['enum_value'] = forms.CharField()

The dynanic field enum_value is defined in the last line. Unfortunately, this does not work as expected: the form is rendered with the two static fields (name and description) but the dynamic field enum_value is not visible. The problem seems to lie in the use of the FormHelper class. If I modify my example as follows:

class DataTypeForm(forms.Form):
    name = forms.CharField()
    description = forms.CharField(widget=forms.Textarea)

    def __init__(self, *args, **kwargs):
        self.mode = kwargs.pop('mode')
        super(DataTypeForm, self).__init__(*args, **kwargs)
#        self.helper = FormHelper(self)
#        self.helper.wrapper_class = 'row'
#        self.helper.label_class = 'col-md-2'
#        self.helper.field_class = 'col-md-8'
#        self.helper.add_input(Submit('submit', 'Submit'))
        self.fields['enum_value'] = forms.CharField()

then, things work as expected and all three fields in my form are correctly rendered. Is there any way I can get the dynamically defined field correctly rendered even when using the FormHelper class?


Solution

  • Placing the dynamic field enum_value before the creation of the FormHelper should work.

    class DataTypeForm(forms.Form):
        name = forms.CharField()
        description = forms.CharField(widget=forms.Textarea)
    
        def __init__(self, *args, **kwargs):
            self.mode = kwargs.pop('mode')
            super(DataTypeForm, self).__init__(*args, **kwargs)
            self.fields['enum_value'] = forms.CharField()
            self.helper = FormHelper(self)
            self.helper.wrapper_class = 'row'
            self.helper.label_class = 'col-md-2'
            self.helper.field_class = 'col-md-8'
            self.helper.add_input(Submit('submit', 'Submit'))