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