Add CSS to form field in django template

Question:

I want to use bootstrap on django form. To do so I need to add .form-control class to each field. My workaround is:

def __init__(self, *args, **kwargs):
    super(SomeForm, self).__init__(*args, **kwargs)
    for field in self.fields:
        self.fields[field].widget.attrs = {
            'class': 'form-control'
        }
{% for field in form %}
    <div class="form-group">
        {{ field.label_tag }}
        {{ field }}
    </div>
{% endfor %}

But I believe it’s wrong to put CSS in python code (if I would want to use another CSS framework, I would have to change form class). How can I move the class to template? I would not like to use crispy not to be bound to bootstrap.

Answers:

You can use a custom template tag for adding a class, see more information here

You will have to create a new module inside the templatetags directory:

myapp/
    __init__.py
    models.py
    templatetags/
        __init__.py
        extra_filters.py <-- Name it as you prefer
    views.py
    forms.py

The content of your extra_filters.py module can be something like this:

from django import template

register = template.Library()


@register.filter(name='addclass')
def addclass(field, myclass):
    return field.as_widget(attrs={"class": myclass})

Now in your template, load the new filter and use it as follows:

{% load extra_filters %}

{% for field in form %}
    <div class="form-group">
        {{ field.label_tag }}
        {{ field|addclass:"form-control" }}
    </div>
{% endfor %}
Answered By: acg

Add form-control css class to the widgets.

The form class is the access point of the input tags through widgets. By changing the widget attr from the constructor method in form.Form

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    
        for field in self.visible_fields():
            field.field.widget.attrs.update({'class': 'form-control'})
Answered By: Shankar Balaji