I am trying to stylize my form using bootstrap. As you know bootstrap uses a lot of classes in order to do what it does. By googling I have found to inject some new classes into my form I could use widgets with django. My form is as follows:
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.EmailField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].label = 'Password'
self.fields['password2'].label = 'Password Confirmation'
self.fields['first_name'].label = 'First Name'
self.fields['last_name'].label = 'Last Name'
self.fields['password1'].help_text = None
self.fields['password2'].help_text = None
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2' )
help_texts = {
'username': None,
}
widgets = {
'username': forms.TextInput(
attrs={
'class': 'form-control'
}
),
'first_name': forms.TextInput(
attrs={
'class': 'form-control'
}
),
'last_name': forms.TextInput(
attrs={
'class': 'form-control'
}
),
'email': forms.EmailInput(
attrs={
'class': 'form-control'
}
),
'password1': forms.PasswordInput(
attrs={
'class': 'form-control'
}
),
'password2': forms.PasswordInput(
attrs={
'class': 'form-control'
}
)
}
But for some reason this is only applying the class to the username field in HTML. It does not apply the class 'form-control' to anything else. Is this some simple format issue I am overlooking or am I doing something wrong? Any help is greatly appreciated!
Meta.widgets
only applies to the automatically created form fields. If you are manually creating some of them, you need to specify your widgets there.
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=30, widget=forms.TextInput(
attrs={
'class': 'form-control'
}
))
last_name = forms.CharField(max_length=30, widget=forms.TextInput(
attrs={
'class': 'form-control'
}
))
email = forms.EmailField(widget=forms.EmailInput(
attrs={
'class': 'form-control'
}
))
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].label = 'Password'
self.fields['password2'].label = 'Password Confirmation'
self.fields['first_name'].label = 'First Name'
self.fields['last_name'].label = 'Last Name'
self.fields['password1'].help_text = None
self.fields['password2'].help_text = None
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2' )
help_texts = {
'username': None,
}
widgets = {
'username': forms.TextInput(
attrs={
'class': 'form-control'
}
),
'password1': forms.PasswordInput(
attrs={
'class': 'form-control'
}
),
'password2': forms.PasswordInput(
attrs={
'class': 'form-control'
}
)
}
This explains the situation only for the first_name
, last_name
and email
. For the password1
and password2
the situation is actually the same, but it's a bit obscured, as those fields are manually defined in your parent class, UserCreationForm
. You need to define them again to change the widget. Alternatively, you can overwrite the widgets in __init__
of your form class.