Search code examples
pythondjangoformswidget

Django: Use widgets in Form's init method?


Why the widget for the field defined as a class attribute is working, but it is not for the instance attribute inside the __init__ method? (I need the init method)

class CropForm(forms.ModelForm):

    class Meta:
        model = CropModel
        fields = ['name', 'label']

    label = forms.CharField(label='label',
                        widget=forms.TextInput(attrs={'class': 'input'}))

    def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)
        self.name = forms.CharField(label='name',
                            widget=forms.TextInput(attrs={'class': 'input'}))

form image

How do I get the widget in the __init__ method to work? Thanks.


Solution

  • You are quite close:

    class CropForm(forms.ModelForm):
    
        class Meta:
            model = CropModel
            fields = ['name', 'label']
    
        label = forms.CharField(
            label='label', widget=forms.TextInput(attrs={'class': 'input'})
        )
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.fields['name'] = forms.CharField(
                label='name', widget=forms.TextInput(attrs={'class': 'input'})
            )

    Django's Form uses metaprogramming to look what form fields are defined. Each time you init the form, copies are made in self.fields that are then rendered. The form will thus, when rendered, not look at class attributes, but at the self.fields dictionary.


    Note: Models normally have no …Model suffix. Therefore it might be better to rename CropModel to Crop.