summaryrefslogtreecommitdiff
path: root/django/forms/models.py
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2010-01-21 02:28:03 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2010-01-21 02:28:03 +0000
commit408d4310291cd1287f3dbc05aaeb5d205eba8751 (patch)
tree88788fcaa4c5fc3f33aacd66ef0c8a0adc7375cc /django/forms/models.py
parent856a39e841080abc34e8ae3bb2b20f780c33762d (diff)
Fixed #12596. Calling super from a ModelForm's clean method is once again optional. Failing to call super only skips unique validation as documented. Thanks for the initial patch and tests, carljm.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12269 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/forms/models.py')
-rw-r--r--django/forms/models.py54
1 files changed, 44 insertions, 10 deletions
diff --git a/django/forms/models.py b/django/forms/models.py
index cce2319471..ec28b446bd 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -250,6 +250,16 @@ class BaseModelForm(BaseForm):
super(BaseModelForm, self).__init__(data, files, auto_id, prefix, object_data,
error_class, label_suffix, empty_permitted)
+ def _update_errors(self, message_dict):
+ for k, v in message_dict.items():
+ if k != NON_FIELD_ERRORS:
+ self._errors.setdefault(k, self.error_class()).extend(v)
+ # Remove the data from the cleaned_data dict since it was invalid
+ if k in self.cleaned_data:
+ del self.cleaned_data[k]
+ if NON_FIELD_ERRORS in message_dict:
+ messages = message_dict[NON_FIELD_ERRORS]
+ self._errors.setdefault(NON_FIELD_ERRORS, self.error_class()).extend(messages)
def _get_validation_exclusions(self):
"""
@@ -281,21 +291,45 @@ class BaseModelForm(BaseForm):
return exclude
def clean(self):
+ self.validate_unique()
+ return self.cleaned_data
+
+ def _clean_fields(self):
+ """
+ Cleans the form fields, constructs the instance, then cleans the model
+ fields.
+ """
+ super(BaseModelForm, self)._clean_fields()
opts = self._meta
self.instance = construct_instance(self, self.instance, opts.fields, opts.exclude)
exclude = self._get_validation_exclusions()
try:
- self.instance.full_clean(exclude=exclude)
+ self.instance.clean_fields(exclude=exclude)
except ValidationError, e:
- for k, v in e.message_dict.items():
- if k != NON_FIELD_ERRORS:
- self._errors.setdefault(k, ErrorList()).extend(v)
- # Remove the data from the cleaned_data dict since it was invalid
- if k in self.cleaned_data:
- del self.cleaned_data[k]
- if NON_FIELD_ERRORS in e.message_dict:
- raise ValidationError(e.message_dict[NON_FIELD_ERRORS])
- return self.cleaned_data
+ self._update_errors(e.message_dict)
+
+ def _clean_form(self):
+ """
+ Runs the instance's clean method, then the form's. This is becuase the
+ form will run validate_unique() by default, and we should run the
+ model's clean method first.
+ """
+ try:
+ self.instance.clean()
+ except ValidationError, e:
+ self._update_errors(e.message_dict)
+ super(BaseModelForm, self)._clean_form()
+
+ def validate_unique(self):
+ """
+ Calls the instance's validate_unique() method and updates the form's
+ validation errors if any were raised.
+ """
+ exclude = self._get_validation_exclusions()
+ try:
+ self.instance.validate_unique(exclude=exclude)
+ except ValidationError, e:
+ self._update_errors(e.message_dict)
def save(self, commit=True):
"""