Form validators that always get tested
February 28, 2006
I needed to make a form that had two inputs, and wanted to require that one or both fields be filled in. While poking around in django.core.formfields, I noticed the following check:
if (field.is_required
or new_data.get(field.field_name, False)
or hasattr(validator, 'always_test')):
Ah ha! What is this always_test I see here? The devs must have already thought of a situation like this, but just failed to mention it in the documentation. Anyway, on to the to the custom form:
from django.core import formfields, validators
class ItemAddForm(formfields.Manipulator):
def __init__(self):
self.fields = [
formfields.TextField(field_name="name",
length=50, maxlength=100,
validator_list=[self.oneIsRequried]),
formfields.URLField(field_name="url",
validator_list=[self.oneIsRequried]),
]
def oneIsRequried(self, field_data, all_data):
if not all_data['name'] and not all_data['url']:
raise validators.ValidationError, \
"One of either name or URL must be filled in."
oneIsRequried.always_test = True
After defining the oneIsRequired method, I set its always_test attribute to True. You see, normally, a field's validators will not get run if the field is left blank. Here, the two fields will always get tested against the oneIsRequired validator method, blank or not.
Note
Technically, I did not need to put the oneIsRequired in both fields' validator_list parameters, but by listing it in both, each field will get the error message in the form.errors dict.