Fixed #20228 - Documented unique_for_date and exclude behavior.

Thanks Deepak Thukral for the patch.
This commit is contained in:
Tim Graham 2013-05-28 09:56:14 -04:00
parent 8365d76da0
commit d321d1acf0
3 changed files with 41 additions and 3 deletions

View File

@ -293,7 +293,12 @@ records with the same ``title`` and ``pub_date``.
Note that if you set this to point to a :class:`DateTimeField`, only the date Note that if you set this to point to a :class:`DateTimeField`, only the date
portion of the field will be considered. portion of the field will be considered.
This is enforced by model validation but not at the database level. This is enforced by :meth:`Model.validate_unique()` during model validation
but not at the database level. If any :attr:`~Field.unique_for_date` constraint
involves fields that are not part of a :class:`~django.forms.ModelForm` (for
example, if one of the fields is listed in ``exclude`` or has
:attr:`editable=False<Field.editable>`), :meth:`Model.validate_unique()` will
skip validation for that particular constraint.
``unique_for_month`` ``unique_for_month``
-------------------- --------------------

View File

@ -207,7 +207,17 @@ class Post(models.Model):
posted = models.DateField() posted = models.DateField()
def __str__(self): def __str__(self):
return self.name return self.title
@python_2_unicode_compatible
class DateTimePost(models.Model):
title = models.CharField(max_length=50, unique_for_date='posted', blank=True)
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.DateTimeField(editable=False)
def __str__(self):
return self.title
class DerivedPost(Post): class DerivedPost(Post):
pass pass

View File

@ -24,7 +24,7 @@ from .models import (Article, ArticleStatus, BetterAuthor, BigInt,
DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle, DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle,
ImprovedArticleWithParentLink, Inventory, Post, Price, ImprovedArticleWithParentLink, Inventory, Post, Price,
Product, TextFile, AuthorProfile, Colour, ColourfulItem, Product, TextFile, AuthorProfile, Colour, ColourfulItem,
ArticleStatusNote, test_images) ArticleStatusNote, DateTimePost, test_images)
if test_images: if test_images:
from .models import ImageFile, OptionalImageFile from .models import ImageFile, OptionalImageFile
@ -76,6 +76,12 @@ class PostForm(forms.ModelForm):
fields = '__all__' fields = '__all__'
class DateTimePostForm(forms.ModelForm):
class Meta:
model = DateTimePost
fields = '__all__'
class DerivedPostForm(forms.ModelForm): class DerivedPostForm(forms.ModelForm):
class Meta: class Meta:
model = DerivedPost model = DerivedPost
@ -682,6 +688,23 @@ class UniqueTest(TestCase):
self.assertEqual(len(form.errors), 1) self.assertEqual(len(form.errors), 1)
self.assertEqual(form.errors['posted'], ['This field is required.']) self.assertEqual(form.errors['posted'], ['This field is required.'])
def test_unique_for_date_in_exclude(self):
"""If the date for unique_for_* constraints is excluded from the
ModelForm (in this case 'posted' has editable=False, then the
constraint should be ignored."""
p = DateTimePost.objects.create(title="Django 1.0 is released",
slug="Django 1.0", subtitle="Finally",
posted=datetime.datetime(2008, 9, 3, 10, 10, 1))
# 'title' has unique_for_date='posted'
form = DateTimePostForm({'title': "Django 1.0 is released", 'posted': '2008-09-03'})
self.assertTrue(form.is_valid())
# 'slug' has unique_for_year='posted'
form = DateTimePostForm({'slug': "Django 1.0", 'posted': '2008-01-01'})
self.assertTrue(form.is_valid())
# 'subtitle' has unique_for_month='posted'
form = DateTimePostForm({'subtitle': "Finally", 'posted': '2008-09-30'})
self.assertTrue(form.is_valid())
def test_inherited_unique_for_date(self): def test_inherited_unique_for_date(self):
p = Post.objects.create(title="Django 1.0 is released", p = Post.objects.create(title="Django 1.0 is released",
slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3)) slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3))