2👍
Create a file, yourapp_template-filters.py
and then place it in templatetags folder in your app:
from django import template
register = template.Library()
@register.filter(name='add_attr')
def add_attribute(field, css):
attrs = {}
definition = css.split(',')
for d in definition:
if ':' not in d:
attrs['class'] = d
else:
key, val = d.split(':')
attrs[key] = val
return field.as_widget(attrs=attrs)
To use it in a Django template, firstly add this widget in the top of the template, similar to the load static widget:{% load yourapp_template-filters %}
And now you can use it on any form widget as a function, like so:
{% if form.user_name.errors %}
{{ form.user_name|add_attr:"form-control is-invalid" }}
{% else %}
{{form.user_name|add_attr:"form-control"}}
{% endif %}
1👍
@ehsan nnnnn‘s answer is great! I tried it, and it works.
I want to clarify and extend it a little bit.
Initialization:
Source: https://docs.djangoproject.com/en/4.0/howto/custom-template-tags/
The app should contain a templatetags directory, at the same level as models.py, views.py, etc. Do not forget to add init.py in the directory! (as stated in the doc)
Attribute declaration:
The code provided by @ehsan nnnnn is helpful if you completely override the attributes section. I have based my code entirely on @ehsan nnnnn‘s solution and extended it to preserve the previous attributes.
NOTE: I am using Python 3.10.1; if you are somehow still using a version before f-string or do not like f-strings, correct it to whatever your heart desires.
Here is my solution:
# templatetags\add_attr.py
from django import template
register = template.Library()
@register.filter(name='add_attr')
def add_attribute(field, css):
attrs = field.subwidgets[0].data['attrs'] # Accessing the already declared attributes
definition = css.split(',')
for d in definition:
if ':' not in d:
attrs['class'] += f" {d}" # Extending the class string
else:
key, val = d.split(':')
attrs[key] += f'{val}' # Extending the `key` string
return field.as_widget(attrs=attrs)
{% comment %} HTML template {% endcomment %}
{% if form.username.errors %}
{{form.username|add_attr:'is-invalid'}}
{% else %}
{{ form.username }}
{% endif %}
Tested on:
- Python 3.10.1
- Django 4.0
- Bootstrap 5.1
- [Django]-Get ID of Django record after it has been created in a ModelViewSet
- [Django]-Django – Modifying the look of simple search results
- [Django]-Django filters. is_safe doesn't work
- [Django]-Django – Can't pass Environment Variable to Apache/Passenger on the WSGI Interface
- [Django]-Django inline – allow adding disable editing
0👍
Try adding a Meta class to your form and assigning the proper model. For instance:
class BasicUserDataForm(forms.Form):
error_css_class = 'is-invalid'
user_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'placeholder': 'Username', 'class': 'form-control'}))
class Meta:
model = User