diff --git a/django/db/models/base.py b/django/db/models/base.py
index 0335c48..2b909ab 100644
a
|
b
|
class Model(six.with_metaclass(ModelBase)):
|
962 | 962 | return errors |
963 | 963 | |
964 | 964 | def date_error_message(self, lookup_type, field_name, unique_for): |
965 | 965 | opts = self._meta |
966 | 966 | field = opts.get_field(field_name) |
| 967 | code = 'unique_for_' + lookup_type |
967 | 968 | return ValidationError( |
968 | | message=field.error_messages['unique_for_date'], |
969 | | code='unique_for_date', |
| 969 | message=field.error_messages[code], |
| 970 | code=code, |
970 | 971 | params={ |
971 | 972 | 'model': self, |
972 | 973 | 'model_name': six.text_type(capfirst(opts.verbose_name)), |
973 | 974 | 'lookup_type': lookup_type, |
974 | 975 | 'field': field_name, |
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 56c25f0..2d35f68 100644
a
|
b
|
class Field(RegisterLookupMixin):
|
104 | 104 | 'invalid_choice': _('Value %(value)r is not a valid choice.'), |
105 | 105 | 'null': _('This field cannot be null.'), |
106 | 106 | 'blank': _('This field cannot be blank.'), |
107 | 107 | 'unique': _('%(model_name)s with this %(field_label)s ' |
108 | 108 | 'already exists.'), |
109 | | # Translators: The 'lookup_type' is one of 'date', 'year' or 'month'. |
110 | | # Eg: "Title must be unique for pub_date year" |
111 | | 'unique_for_date': _("%(field_label)s must be unique for " |
112 | | "%(date_field_label)s %(lookup_type)s."), |
| 109 | 'unique_for_date': _("%(field_label)s must be unique for the date " |
| 110 | "of the field %(date_field_label)s."), |
| 111 | 'unique_for_year': _("%(field_label)s must be unique for the year " |
| 112 | "of the field %(date_field_label)s."), |
| 113 | 'unique_for_month': _("%(field_label)s must be unique for the month " |
| 114 | "of the field %(date_field_label)s."), |
113 | 115 | } |
114 | 116 | class_lookups = default_lookups.copy() |
115 | 117 | |
116 | 118 | # Generic field type description, usually overridden by subclasses |
117 | 119 | def _description(self): |
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index 783a031..21f7e75 100644
a
|
b
|
class UniqueTest(TestCase):
|
758 | 758 | p = Post.objects.create(title="Django 1.0 is released", |
759 | 759 | slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) |
760 | 760 | form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) |
761 | 761 | self.assertFalse(form.is_valid()) |
762 | 762 | self.assertEqual(len(form.errors), 1) |
763 | | self.assertEqual(form.errors['title'], ['Title must be unique for Posted date.']) |
| 763 | self.assertEqual(form.errors['title'], ['Title must be unique for the date of the field Posted.']) |
764 | 764 | form = PostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) |
765 | 765 | self.assertTrue(form.is_valid()) |
766 | 766 | form = PostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) |
767 | 767 | self.assertTrue(form.is_valid()) |
768 | 768 | form = PostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) |
769 | 769 | self.assertFalse(form.is_valid()) |
770 | 770 | self.assertEqual(len(form.errors), 1) |
771 | | self.assertEqual(form.errors['slug'], ['Slug must be unique for Posted year.']) |
| 771 | self.assertEqual(form.errors['slug'], ['Slug must be unique for the year of the field Posted.']) |
772 | 772 | form = PostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) |
773 | 773 | self.assertFalse(form.is_valid()) |
774 | | self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for Posted month.']) |
| 774 | self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for the month of the field Posted.']) |
775 | 775 | form = PostForm({'subtitle': "Finally", "title": "Django 1.0 is released", |
776 | 776 | "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) |
777 | 777 | self.assertTrue(form.is_valid()) |
778 | 778 | form = PostForm({'title': "Django 1.0 is released"}) |
779 | 779 | self.assertFalse(form.is_valid()) |
… |
… |
class UniqueTest(TestCase):
|
808 | 808 | p = Post.objects.create(title="Django 1.0 is released", |
809 | 809 | slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) |
810 | 810 | form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'}) |
811 | 811 | self.assertFalse(form.is_valid()) |
812 | 812 | self.assertEqual(len(form.errors), 1) |
813 | | self.assertEqual(form.errors['title'], ['Title must be unique for Posted date.']) |
| 813 | self.assertEqual(form.errors['title'], ['Title must be unique for the date of the field Posted.']) |
814 | 814 | form = DerivedPostForm({'title': "Work on Django 1.1 begins", 'posted': '2008-09-03'}) |
815 | 815 | self.assertTrue(form.is_valid()) |
816 | 816 | form = DerivedPostForm({'title': "Django 1.0 is released", 'posted': '2008-09-04'}) |
817 | 817 | self.assertTrue(form.is_valid()) |
818 | 818 | form = DerivedPostForm({'slug': "Django 1.0", 'posted': '2008-01-01'}) |
819 | 819 | self.assertFalse(form.is_valid()) |
820 | 820 | self.assertEqual(len(form.errors), 1) |
821 | | self.assertEqual(form.errors['slug'], ['Slug must be unique for Posted year.']) |
| 821 | self.assertEqual(form.errors['slug'], ['Slug must be unique for the year of the field Posted.']) |
822 | 822 | form = DerivedPostForm({'subtitle': "Finally", 'posted': '2008-09-30'}) |
823 | 823 | self.assertFalse(form.is_valid()) |
824 | | self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for Posted month.']) |
| 824 | self.assertEqual(form.errors['subtitle'], ['Subtitle must be unique for the month of the field Posted.']) |
825 | 825 | form = DerivedPostForm({'subtitle': "Finally", "title": "Django 1.0 is released", |
826 | 826 | "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) |
827 | 827 | self.assertTrue(form.is_valid()) |
828 | 828 | |
829 | 829 | def test_unique_for_date_with_nullable_date(self): |
diff --git a/tests/validation/test_unique.py b/tests/validation/test_unique.py
index 76c7ec1..5e60981 100644
a
|
b
|
class PerformUniqueChecksTest(TestCase):
|
116 | 116 | slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) |
117 | 117 | |
118 | 118 | p = Post(title="Django 1.0 is released", posted=datetime.date(2008, 9, 3)) |
119 | 119 | with self.assertRaises(ValidationError) as cm: |
120 | 120 | p.full_clean() |
121 | | self.assertEqual(cm.exception.message_dict, {'title': ['Title must be unique for Posted date.']}) |
| 121 | self.assertEqual(cm.exception.message_dict, {'title': ['Title must be unique for the date of the field Posted.']}) |
122 | 122 | |
123 | 123 | # Should work without errors |
124 | 124 | p = Post(title="Work on Django 1.1 begins", posted=datetime.date(2008, 9, 3)) |
125 | 125 | p.full_clean() |
126 | 126 | |
… |
… |
class PerformUniqueChecksTest(TestCase):
|
129 | 129 | p.full_clean() |
130 | 130 | |
131 | 131 | p = Post(slug="Django 1.0", posted=datetime.datetime(2008, 1, 1)) |
132 | 132 | with self.assertRaises(ValidationError) as cm: |
133 | 133 | p.full_clean() |
134 | | self.assertEqual(cm.exception.message_dict, {'slug': ['Slug must be unique for Posted year.']}) |
| 134 | self.assertEqual(cm.exception.message_dict, {'slug': ['Slug must be unique for the year of the field Posted.']}) |
135 | 135 | |
136 | 136 | p = Post(subtitle="Finally", posted=datetime.datetime(2008, 9, 30)) |
137 | 137 | with self.assertRaises(ValidationError) as cm: |
138 | 138 | p.full_clean() |
139 | | self.assertEqual(cm.exception.message_dict, {'subtitle': ['Subtitle must be unique for Posted month.']}) |
| 139 | self.assertEqual(cm.exception.message_dict, {'subtitle': ['Subtitle must be unique for the month of the field Posted.']}) |
140 | 140 | |
141 | 141 | p = Post(title="Django 1.0 is released") |
142 | 142 | with self.assertRaises(ValidationError) as cm: |
143 | 143 | p.full_clean() |
144 | 144 | self.assertEqual(cm.exception.message_dict, {'posted': ['This field cannot be null.']}) |