Commit d321d1ac authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #20228 - Documented unique_for_date and exclude behavior.

Thanks Deepak Thukral for the patch.
parent 8365d76d
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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
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``
--------------------
+11 −1
Original line number Diff line number Diff line
@@ -207,7 +207,17 @@ class Post(models.Model):
    posted = models.DateField()

    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):
    pass
+24 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ from .models import (Article, ArticleStatus, BetterAuthor, BigInt,
    DerivedPost, ExplicitPK, FlexibleDatePost, ImprovedArticle,
    ImprovedArticleWithParentLink, Inventory, Post, Price,
    Product, TextFile, AuthorProfile, Colour, ColourfulItem,
    ArticleStatusNote, test_images)
    ArticleStatusNote, DateTimePost, test_images)

if test_images:
    from .models import ImageFile, OptionalImageFile
@@ -76,6 +76,12 @@ class PostForm(forms.ModelForm):
        fields = '__all__'


class DateTimePostForm(forms.ModelForm):
    class Meta:
        model = DateTimePost
        fields = '__all__'


class DerivedPostForm(forms.ModelForm):
    class Meta:
        model = DerivedPost
@@ -682,6 +688,23 @@ class UniqueTest(TestCase):
        self.assertEqual(len(form.errors), 1)
        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):
        p = Post.objects.create(title="Django 1.0 is released",
            slug="Django 1.0", subtitle="Finally", posted=datetime.date(2008, 9, 3))