I was playing around with a custom ErrorList the other day. The idea is to be able modify the way errors display in a template. The Django documentation gives an example of this technique.
(One thing I noticed while overriding methods in ErrorList, when I only defined one of the existing display methods, such as as_ul
, the code was ignored. Only when I also included my own __unicode__
method pointing to my new code did it work correctly. I’m using Django 1.3 right now, so you may find things better in a future version.)
My challenge was to use my custom ErrorList with a form in a class-based views environment. There are several ways to accomplish this.
Handle It in the View
In the view, one can override the get_form_kwargs
method to add the error_class
attribute to the kwargs
dictionary.
def get_form_kwargs(self):
kwargs = super(MyViewName,self).get_form_kwargs()
kwargs.update({'error_class': MyCustomErrorList})
return kwargs
Since I’m a big mixin fan, I developed this little gem that performs this task:
class CustomErrorClassViewMixin(object):
''' Will set the error_class attribute
on the form with the provided value
found in the error_class variable '''
error_class = None
def get_form_kwargs(self):
# Make sure that the error_class attribute is set on the
# view, or raise a configuration error.
if self.error_class is None:
raise ImproperlyConfigured("'CustomErrorClassViewMixin' requires "
"'error_class' attribute to be set.")
kwargs = super(CustomErrorClassViewMixin,self).get_form_kwargs()
kwargs.update({'error_class': self.error_class})
return kwargs
Include this mixin in your view class definition (class MyView(CustomErrorClassViewMixin, CreateView)
) and set a value for the error_class
variable, and it will handle the rest.
Form Level Fun
In some situations, it may be desired to use the custom ErrorList on every use of the form. To do this, a little work in the form’s __init__
method is required.
def __init__(self, *args, **kwargs):
## Set the error_class attribute
kwargs['error_class'] = MyCustomErrorList
## Call the parent method
super(MyForm, self).__init__(*args, **kwargs)
Here’s a mixin for this scenario (I love the mixins!):
class CustomErrorClassFormMixin(object):
''' Allows the declaration of a custom error_class for a form
Requires the error_class attribute to be provided
'''
error_class = None ## Default to none
def __init__(self, *args, **kwargs):
# Make sure that the error_class attribute is set on the
# form, or raise a configuration error.
if self.error_class is None:
raise ImproperlyConfigured("'CustomErrorClassFormMixin' requires "
"'error_class' attribute to be set.")
## Set the error_class attribute
kwargs['error_class'] = self.error_class
## Call the parent method
super(CustomErrorClassFormMixin, self).__init__(*args, **kwargs)
A couple of notes for this one:
- The mixin must be declared before the form class in order to update the
error_class
inkwargs
before the form’s__init__()
method fires - The
error_class
attribute must be defined
Best Looking Errors in Town
Now, your users can make gorgeous errors. Let me know how this works for you.