Form validators that always get tested

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.



blog comments powered by Disqus