diff options
| author | Loic Bistuer <loic.bistuer@sixmedia.com> | 2013-11-12 00:56:01 +0700 |
|---|---|---|
| committer | Loic Bistuer <loic.bistuer@sixmedia.com> | 2013-11-30 01:00:53 +0700 |
| commit | f563c339ca2eed81706ab17726c79a6f00d7c553 (patch) | |
| tree | 0cb105d3b8d29c4cc135d8862f9ee8dceb5ebc98 /django/forms/forms.py | |
| parent | 7e2d61a9724644d6d1c7ce9361d9fd5be3e2ab86 (diff) | |
Fixed #20867 -- Added the Form.add_error() method.
Refs #20199 #16986.
Thanks @akaariai, @bmispelon, @mjtamlyn, @timgraham for the reviews.
Diffstat (limited to 'django/forms/forms.py')
| -rw-r--r-- | django/forms/forms.py | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/django/forms/forms.py b/django/forms/forms.py index 15bbff229b..350b8b8993 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -290,6 +290,51 @@ class BaseForm(object): prefix = self.add_prefix(fieldname) return field.widget.value_from_datadict(self.data, self.files, prefix) + def add_error(self, field, error): + """ + Update the content of `self._errors`. + + The `field` argument is the name of the field to which the errors + should be added. If its value is None the errors will be treated as + NON_FIELD_ERRORS. + + The `error` argument can be a single error, a list of errors, or a + dictionary that maps field names to lists of errors. What we define as + an "error" can be either a simple string or an instance of + ValidationError with its message attribute set and what we define as + list or dictionary can be an actual `list` or `dict` or an instance + of ValidationError with its `error_list` or `error_dict` attribute set. + + If `error` is a dictionary, the `field` argument *must* be None and + errors will be added to the fields that correspond to the keys of the + dictionary. + """ + if not isinstance(error, ValidationError): + # Normalize to ValidationError and let its constructor + # do the hard work of making sense of the input. + error = ValidationError(error) + + if hasattr(error, 'error_dict'): + if field is not None: + raise TypeError( + "The argument `field` must be `None` when the `error` " + "argument contains errors for multiple fields." + ) + else: + error = dict(error) + else: + error = {field or NON_FIELD_ERRORS: list(error)} + + for field, error_list in error.items(): + if field not in self.errors: + if field != NON_FIELD_ERRORS and field not in self.fields: + raise ValueError( + "'%s' has no field named '%s'." % (self.__class__.__name__, field)) + self._errors[field] = self.error_class() + self._errors[field].extend(error_list) + if field in self.cleaned_data: + del self.cleaned_data[field] + def full_clean(self): """ Cleans all of self.data and populates self._errors and @@ -303,6 +348,7 @@ class BaseForm(object): # 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() @@ -324,15 +370,13 @@ class BaseForm(object): value = getattr(self, 'clean_%s' % name)() self.cleaned_data[name] = value except ValidationError as e: - self._errors[name] = self.error_class(e.messages) - if name in self.cleaned_data: - del self.cleaned_data[name] + self.add_error(name, e) def _clean_form(self): try: cleaned_data = self.clean() except ValidationError as e: - self._errors[NON_FIELD_ERRORS] = self.error_class(e.messages) + self.add_error(None, e) else: if cleaned_data is not None: self.cleaned_data = cleaned_data |
