From 106089c18e3c15a801fc339d773f8d227228924d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Honza=20Kr=C3=A1l?= Date: Wed, 12 Aug 2009 20:10:54 +0000 Subject: [PATCH] [soc2009/model-validation] Make sure custom messages work for models as well git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11437 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/base.py | 9 ++++++++- django/db/models/fields/__init__.py | 10 ++++++++-- tests/modeltests/validation/models.py | 16 ++++++++++++++-- .../validation/test_custom_messages.py | 16 ++++++++++++++++ tests/modeltests/validation/tests.py | 3 +-- 5 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 tests/modeltests/validation/test_custom_messages.py diff --git a/django/db/models/base.py b/django/db/models/base.py index f4a1c28179..6ebe12054f 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -774,7 +774,14 @@ class Model(object): try: v(value, obj=self) except ValidationError, e: - errors.setdefault(f.name, []).extend(e.messages) + error_list = errors.setdefault(f.name, []) + if hasattr(e, 'code') and e.code in f.error_messages: + message = f.error_messages[e.code] + if e.params: + message = message % e.params + error_list.append(message) + else: + error_list.extend(e.messages) try: # TODO: run this only if not errors?? self.validate() diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 8b53cd95c3..a084c976c3 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -168,13 +168,19 @@ class Field(object): errors = [] for v in self.validators: - # don't run complex validators since they need model_instance + # don't run complex validators since they need obj # and must therefore be run on the model level if not isinstance(v, validators.ComplexValidator): try: v(value) except exceptions.ValidationError, e: - errors.extend(e.messages) + if hasattr(e, 'code') and e.code in self.error_messages: + message = self.error_messages[e.code] + if e.params: + message = message % e.params + errors.append(message) + else: + errors.extend(e.messages) if errors: raise exceptions.ValidationError(errors) diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py index c00b7f28d2..6a08f083f1 100644 --- a/tests/modeltests/validation/models.py +++ b/tests/modeltests/validation/models.py @@ -7,7 +7,7 @@ from django.test import TestCase def validate_answer_to_universe(value): if value != 42: - raise ValidationError('This is not the answer to life, universe and everything!') + raise ValidationError('This is not the answer to life, universe and everything!', code='not42') class ValidateFieldNotEqualsOtherField(ComplexValidator): def __init__(self, other_field): @@ -15,7 +15,7 @@ class ValidateFieldNotEqualsOtherField(ComplexValidator): def __call__(self, value, all_values={}, obj=None): if value == self.get_value(self.other_field, all_values, obj): - raise ValidationError("Must not equal to %r's value" % self.other_field) + raise ValidationError("Must not equal to %r's value" % self.other_field, code='not_equal', params=(self.other_field,)) class ModelToValidate(models.Model): name = models.CharField(max_length=100) @@ -52,3 +52,15 @@ class UniqueForDateModel(models.Model): count = models.IntegerField(unique_for_date="start_date", unique_for_year="end_date") order = models.IntegerField(unique_for_month="end_date") name = models.CharField(max_length=100) + +class CustomMessagesModel(models.Model): + other = models.IntegerField(blank=True, null=True) + number = models.IntegerField( + error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'}, + validators=[validate_answer_to_universe, ValidateFieldNotEqualsOtherField('other')] + ) + + + + + diff --git a/tests/modeltests/validation/test_custom_messages.py b/tests/modeltests/validation/test_custom_messages.py new file mode 100644 index 0000000000..059b7f462d --- /dev/null +++ b/tests/modeltests/validation/test_custom_messages.py @@ -0,0 +1,16 @@ +from modeltests.validation import ValidationTestCase + +from models import CustomMessagesModel +class CustomMessagesTest(ValidationTestCase): + def test_custom_complex_validator_message(self): + cmm = CustomMessagesModel(number=42, other=42) + self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['other != me']) + + def test_custom_simple_validator_message(self): + cmm = CustomMessagesModel(number=12) + self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['AAARGH']) + + def test_custom_null_message(self): + cmm = CustomMessagesModel() + self.assertFieldFailsValidationWithMessage(cmm.clean, 'number', ['NULL']) + diff --git a/tests/modeltests/validation/tests.py b/tests/modeltests/validation/tests.py index 150ebd9ccc..4d2a71af35 100644 --- a/tests/modeltests/validation/tests.py +++ b/tests/modeltests/validation/tests.py @@ -1,5 +1,3 @@ -import unittest - from django.core.exceptions import ValidationError, NON_FIELD_ERRORS from django.db import models @@ -8,6 +6,7 @@ from models import * from validators import TestModelsWithValidators from test_unique import GetUniqueCheckTests +from test_custom_messages import CustomMessagesTest class BaseModelValidationTests(ValidationTestCase):