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 %}
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'})
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.
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 %}
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'})