1

What is the correct method for validating input for a custom multiwidget in each of these cases:

  1. if I want to implement a custom Field?
  2. if I want to use an existing database field type (say DateField)?

The motivation for this comes from the following two questions:

  1. How do I use django's multi-widget?
  2. Django subclassing multiwidget

I am specifically interested in the fact that I feel I have cheated. I have used value_from_datadict() like so:

def value_from_datadict(self, data, files, name):

    datelist = [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
    try:   
        D = date(day=int(datelist[0]), month=int(datelist[1]), year=int(datelist[2]))
        return str(D)
    except ValueError:
        return None

Which looks through the POST dictionary and constructs a value for my widget (see linked questions). However, at the same time I've tacked on some validation; namely if the creation of D as a date object fails, I'm returning None which will fail in the is_valid() check.

My third question therefore is should I be doing this some other way? For this case, I do not want a custom field.

Thanks.

Community
  • 1
  • 1

2 Answers2

0

You validate your form fields just like any other fields, implementing the clean_fieldname method in your form. If your validation logic spreads across many form fields (which is nto the same as many widgets!) you put it in your form's clean() method.

http://docs.djangoproject.com/en/1.2/ref/forms/validation/

konryd
  • 541
  • 1
  • 5
  • 12
  • 1
    That makes sense if the validation is unique to the form instance. However, if it's a custom widget that always needs a certain form of validation, adding it manually to every form that widget is used is illogical and violates DRY. – Chris Pratt May 02 '11 at 16:24
0

According to the documentation, validation is the responsibility of the field behind the widget, not the widget itself. Widgets should do nothing but present the input for the user and pass input data back to the field.

So, if you want to validate data that's been submitted, you should write a validator.

This is especially important with MultiWidgets, as you can have more than one aspect of the data error out. Each aspect needs to be returned to the user for consideration, and the built in way to do that is to write validators and place them in the validators attribute of the field.

Contrary to the documentation, you don't have to do this per form. You can, instead, extend one of the built in forms and add an entry to default_validators.

One more note: If you're going to implement a MultiWidget, your form is going to pass some sort of 'compressed' data back to it to render. The docs say:

This method takes a single “compressed” value from the field and returns a list of “decompressed” values. The input value can be assumed valid, but not necessarily non-empty.

-Widgets

Just make sure you're handling that output correctly and you'll be fine.

Patrick
  • 165
  • 2
  • 10