Friday, July 8, 2011

How Django form calls clean() method

I was reading the Django docs on forms which says:
Validation of a Form is split into several steps ... [calls]
- [1] to_python()
- [2] validate()
- [3] run_validators()
- [4] clean()
- [5] clean_()


This is how these things work in the source code:

1. each field's clean() method takes care of the first 3 items

# src/django/django/forms/fields.py, comments mine

    class Field(object):
        ...
        def clean(self, value):
            """
            Validates the given value and returns its "cleaned" value as an
            appropriate Python object.

            Raises ValidationError for any errors.
            """
            value = self.to_python(value)    # [1]
            self.validate(value)             # [2]
            self.run_validators(value)       # [3]
            return value

2. aoeu

# src/django/django/forms/fields.py, comments mine

    class BaseForm(StrAndUnicode):
        ...
        def full_clean(self):
            """
            Cleans all of self.data and populates self._errors and
            self.cleaned_data.
            """
            self._errors = ErrorDict()
            if not self.is_bound: # Stop further processing.
                return
            self.cleaned_data = {}
            # If the form is permitted to be empty, and none of the form data has
            # changed from the initial data, short circuit any validation.
            if self.empty_permitted and not self.has_changed():
                return
            self._clean_fields()
            self._clean_form()
            self._post_clean()
            if self._errors:
                del self.cleaned_data

        def _clean_fields(self):
            for name, field in self.fields.items():
                # value_from_datadict() gets the data from the data dictionaries.
                # Each widget type knows how to retrieve its own data, because some
                # widgets split data over several HTML fields.
                value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
                try:
                    if isinstance(field, FileField):
                        initial = self.initial.get(name, field.initial)
                        # calls step 1's stuff
                        value = field.clean(value, initial) 
                    else:
                        value = field.clean(value)
                    self.cleaned_data[name] = value
                    if hasattr(self, 'clean_%s' % name):
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value
                except ValidationError, e:
                    self._errors[name] = self.error_class(e.messages)
                    if name in self.cleaned_data:
                        del self.cleaned_data[name]

... calls some alias ...
figure it out yourself

No comments:

Post a Comment