Custom ErrorList in a Form

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 in kwargs 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.