From 14fa7f9907bae2c13c33789fb65d9cae56f6f60b Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 17 Aug 2010 07:08:26 +0000 Subject: [PATCH] [1.2.X] Fixed #14102 -- Ensure that fields that have been excluded from a form aren't included in the unique_for_* checks, either. Thanks to Travis Cline for the report and fix. Backport of r13598 from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@13599 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/db/models/base.py | 9 ++++----- tests/modeltests/model_forms/tests.py | 4 ++++ tests/modeltests/validation/test_unique.py | 9 +++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index 545111877c..69da9144ca 100644 --- a/AUTHORS +++ b/AUTHORS @@ -108,6 +108,7 @@ answer newbie questions, and generally made Django that much better: Michal Chruszcz Can Burak Çilingir Ian Clelland + Travis Cline Russell Cloran colin@owlfish.com crankycoder@gmail.com diff --git a/django/db/models/base.py b/django/db/models/base.py index 6304e009d3..d1232ee4cf 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1,6 +1,5 @@ import types import sys -import os from itertools import izip import django.db.models.manager # Imported to register signal handler. from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS @@ -16,7 +15,7 @@ from django.db.models.loading import register_models, get_model from django.utils.translation import ugettext_lazy as _ import django.utils.copycompat as copy from django.utils.functional import curry, update_wrapper -from django.utils.encoding import smart_str, force_unicode, smart_unicode +from django.utils.encoding import smart_str, force_unicode from django.utils.text import get_text_list, capfirst from django.conf import settings @@ -744,11 +743,11 @@ class Model(object): continue if f.unique: unique_checks.append((model_class, (name,))) - if f.unique_for_date: + if f.unique_for_date and f.unique_for_date not in exclude: date_checks.append((model_class, 'date', name, f.unique_for_date)) - if f.unique_for_year: + if f.unique_for_year and f.unique_for_year not in exclude: date_checks.append((model_class, 'year', name, f.unique_for_year)) - if f.unique_for_month: + if f.unique_for_month and f.unique_for_month not in exclude: date_checks.append((model_class, 'month', name, f.unique_for_month)) return unique_checks, date_checks diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py index 6a5f9395cc..c5647c714f 100644 --- a/tests/modeltests/model_forms/tests.py +++ b/tests/modeltests/model_forms/tests.py @@ -156,6 +156,10 @@ class UniqueTest(TestCase): form = PostForm({'subtitle': "Finally", "title": "Django 1.0 is released", "slug": "Django 1.0", 'posted': '2008-09-03'}, instance=p) self.assertTrue(form.is_valid()) + form = PostForm({'title': "Django 1.0 is released"}) + self.assertFalse(form.is_valid()) + self.assertEqual(len(form.errors), 1) + self.assertEqual(form.errors['posted'], [u'This field is required.']) def test_inherited_unique_for_date(self): p = Post.objects.create(title="Django 1.0 is released", diff --git a/tests/modeltests/validation/test_unique.py b/tests/modeltests/validation/test_unique.py index 1b966390c4..fb77c4d28c 100644 --- a/tests/modeltests/validation/test_unique.py +++ b/tests/modeltests/validation/test_unique.py @@ -40,6 +40,15 @@ class GetUniqueCheckTests(unittest.TestCase): ), m._get_unique_checks() ) + def test_unique_for_date_exclusion(self): + m = UniqueForDateModel() + self.assertEqual(( + [(UniqueForDateModel, ('id',))], + [(UniqueForDateModel, 'year', 'count', 'end_date'), + (UniqueForDateModel, 'month', 'order', 'end_date')] + ), m._get_unique_checks(exclude='start_date') + ) + class PerformUniqueChecksTest(unittest.TestCase): def setUp(self): # Set debug to True to gain access to connection.queries.