Reputation: 8077
I want to define a class
attribute for the <option/>
tags within a django ChoiceField
, how can I do that?
I tried to set the widget class, and specifying an attribute like so, in forms.py:
field = forms.ChoiceField(choices=[(1, 'foo'), (2, 'bar')], widget=forms.Select(attrs={'class': 'form-control'}))
And rendering inside my template.html
like this:
{{ form.field }}
The output is:
<select name="field" class="form-control" id="id_field">
<option value="1">foo</option>
<option value="2">bar</option>
</select>
And what I want to have is this:
<select name="field" class="form-control" id="id_fields">
<option class="form-control" value="1">foo</option>
<option class="form-control" value="2">bar</option>
</select>
What is the easiest way to do this?
Upvotes: 1
Views: 4177
Reputation: 2192
The easiest way to achieve this is to subclass the Select
widget and set option_inherits_attrs
to True:
class CustomSelect(forms.Select):
option_inherits_attrs = True
Then use your custom widget when creating the form:
class TestForm(forms.Form):
items = forms.ChoiceField(
choices=[(1, 'foo'), (2, 'bar')],
widget=CustomSelect(
attrs={'class': 'form-control'}
)
Upvotes: 2
Reputation: 383
You may create a Template Tag and write a custom template field. It's the best option if you want to reuse attributes.
The app should contain a templatetags directory, at the same level as models.py, views.py, etc. If this doesn’t already exist, create it - don’t forget the __init__.py file to ensure the directory is treated as a Python package.
Create this structure inside your app's folder
Inside filters.py
from django import template
register = template.Library()
@register.filter(name='addclass')
def addclass(value, arg):
return value.as_widget(attrs={'class': arg})
Add {% load filters %}
to your template.html, before {% block content %}
That's how you apply your filter:
{{form.field|addclass:'form-control'}}
Now you should forget about adding classes to your HTML elements inside forms.py
If you disliked the Template Tag way or maybe are just looking for a low-cost temporary solution, you should take a look at this link.
Another way of solving the same problem
Upvotes: 0