diff --git a/AUTHORS b/AUTHORS index 8b6f6544cd..b8c773b602 100644 --- a/AUTHORS +++ b/AUTHORS @@ -128,7 +128,7 @@ answer newbie questions, and generally made Django that much better: Robert Coup Pete Crosier Matt Croydon - Leah Culver + Leah Culver flavio.curella@gmail.com Jure Cuhalev John D'Agostino diff --git a/django/db/models/base.py b/django/db/models/base.py index 9cf083416c..e75eb49695 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -782,9 +782,10 @@ class Model(object): # A unique field if len(unique_check) == 1: field_name = unique_check[0] - field_label = capfirst(opts.get_field(field_name).verbose_name) + field = opts.get_field(field_name) + field_label = capfirst(field.verbose_name) # Insert the error into the error dict, very sneaky - return _(u"%(model_name)s with this %(field_label)s already exists.") % { + return field.error_messages['unique'] % { 'model_name': unicode(model_name), 'field_label': unicode(field_label) } diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 9037265e8b..63d0c21bc1 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -60,6 +60,7 @@ class Field(object): 'invalid_choice': _(u'Value %r is not a valid choice.'), 'null': _(u'This field cannot be null.'), 'blank': _(u'This field cannot be blank.'), + 'unique': _(u'%(model_name)s with this %(field_label)s already exists.'), } # Generic field type description, usually overriden by subclasses diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index bc27a48bc1..5c4bbd06bc 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -210,6 +210,10 @@ The ``error_messages`` argument lets you override the default messages that the field will raise. Pass in a dictionary with keys matching the error messages you want to override. +Error message keys include ``null``, ``blank``, ``invalid``, ``invalid_choice``, +and ``unique``. Additional error message keys are specified for each field in +the `Field types`_ section below. + ``help_text`` ------------- @@ -416,7 +420,8 @@ optional arguments: it's not just a default value that you can override. The admin represents this as an ```` with a JavaScript -calendar, and a shortcut for "Today". +calendar, and a shortcut for "Today". Includes an additional ``invalid_date`` +error message key. .. note:: As currently implemented, setting ``auto_now`` or ``auto_now_add`` to diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py index 861d1440fe..923e5a88c5 100644 --- a/tests/modeltests/validation/models.py +++ b/tests/modeltests/validation/models.py @@ -78,3 +78,7 @@ class FlexibleDatePost(models.Model): slug = models.CharField(max_length=50, unique_for_year='posted', blank=True) subtitle = models.CharField(max_length=50, unique_for_month='posted', blank=True) posted = models.DateField(blank=True, null=True) + +class UniqueErrorsModel(models.Model): + name = models.CharField(max_length=100, unique=True, error_messages={'unique': u'Custom unique name message.'}) + number = models.IntegerField(unique=True, error_messages={'unique': u'Custom unique number message.'}) \ No newline at end of file diff --git a/tests/modeltests/validation/test_unique.py b/tests/modeltests/validation/test_unique.py index 223aa021e4..90616126a5 100644 --- a/tests/modeltests/validation/test_unique.py +++ b/tests/modeltests/validation/test_unique.py @@ -7,7 +7,7 @@ from django.test import TestCase from django.utils import unittest from models import (CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, - UniqueForDateModel, ModelToValidate, Post, FlexibleDatePost) + UniqueForDateModel, ModelToValidate, Post, FlexibleDatePost, UniqueErrorsModel) class GetUniqueCheckTests(unittest.TestCase): @@ -149,3 +149,22 @@ class PerformUniqueChecksTest(TestCase): self.fail("unique_for_month checks shouldn't trigger when the associated DateField is None.") except: self.fail("unique_for_month checks shouldn't explode when the associated DateField is None.") + + def test_unique_errors(self): + m1 = UniqueErrorsModel.objects.create(name='Some Name', number=10) + m = UniqueErrorsModel(name='Some Name', number=11) + try: + m.full_clean() + except ValidationError, e: + self.assertEqual(e.message_dict, {'name': [u'Custom unique name message.']}) + except: + self.fail('unique checks should catch this.') + + m = UniqueErrorsModel(name='Some Other Name', number=10) + try: + m.full_clean() + except ValidationError, e: + self.assertEqual(e.message_dict, {'number': [u'Custom unique number message.']}) + except: + self.fail('unique checks should catch this.') + \ No newline at end of file