Last Updated: September 12, 2017
·
3.41K
· dorfire

Style Django form widgets individually

In a recent project I came across the need to give specific form widgets (e.g. PasswordInput) different CSS classes.

My solution is a class decorator that changes those widgets' attr properties:

def _widget_add_classes(widget, classes):
 initial_classes = widget.attrs.get('class', '')
 widget.attrs['class'] = '%s %s' % (initial_classes, classes) if initial_classes else classes

def style_widgets(widget_classes):
 def wrapper(form_cls):
 for field in form_cls.base_fields.itervalues():
 widget_cls = field.widget.__class__.__name__
 if widget_cls in widget_classes:
 _widget_add_classes(field.widget, widget_classes[widget_cls])
 return form_cls
 return wrapper

Example usage:

@style_widgets({'PasswordInput': 'smallinput'})
class EmailRegistrationForm(forms.Form):
 email = forms.EmailField(label=_('Email address'))
 password1 = forms.CharField(
 label=_('Password'),
 widget=forms.PasswordInput)
 password2 = forms.CharField(
 label=_('Password confirmation'),
 widget=forms.PasswordInput)

I used the same technique to style individual fields by their name. Of course, any other identifier can be used: label / max_length / whatever.