I am trying to add an error class to fields of a each form in a formset if a custom clean method detects errors. This does look to do the trick, I load the page, and the field does have the error class in it. but when in the template I add a custom filter to add a form-control class, everything falls apart.
# in my inlineformset:
def clean(self, *args, **kwargs):
if any(self.errors):
errors = self.errors
return
## 1) Total amount
total_amount = 0
for form in self.forms:
if self.can_delete and self._should_delete_form(form):
continue
amount = form.cleaned_data.get('amount')
total_amount += amount
if total_amount> 100:
for form in self.forms:
form.fields['amount'].widget.attrs.update({'class': 'error special'})
raise ValidationError(_('Total amount cannot exceed 100%'))
And, here is my code for the custom filter:
@register.filter(name = 'add_class')
def add_class(the_field, class_name):
''' Adds class_name to the string of space-separated CSS classes for this field'''
initial_class_names = the_field.css_classes() ## This returns empty string, but it should return 'error special'
class_names = initial_class_names + ' ' + class_name if initial_class_names else class_name
return the_field.as_widget(attrs = {'class': class_names,})
And, in my template:
{# {{ the_field|add_class:"form-control"}} #} #<- This adds the form-control, but removes the other classes added in the clean method
{{ the_field }} {# This shows the two classes for the offending fields, 'error special' #}
I think the problem is with the .css_classes()
method which does not bring in the classes defined on the form. Remember, these classes have been set on these fields and rendering {{ the_field }}
shows the classes were correctly passed down to the template. So, then the question is whether I am using the correct method .css_classes()
or if I should use another method?