[1.8.x] Fixed #15321 -- Honored ancestors unique checks.

Thanks to Tim for the review.

Backport of 79f27f2b61 from master
This commit is contained in:
Aron Podrigal 2015-01-21 22:15:59 -05:00 committed by Simon Charette
parent 3e24ab6f4c
commit fc49e73648
3 changed files with 55 additions and 4 deletions

View File

@ -939,7 +939,7 @@ class Model(six.with_metaclass(ModelBase)):
unique_checks = [] unique_checks = []
unique_togethers = [(self.__class__, self._meta.unique_together)] unique_togethers = [(self.__class__, self._meta.unique_together)]
for parent_class in self._meta.parents.keys(): for parent_class in self._meta.get_parent_list():
if parent_class._meta.unique_together: if parent_class._meta.unique_together:
unique_togethers.append((parent_class, parent_class._meta.unique_together)) unique_togethers.append((parent_class, parent_class._meta.unique_together))
@ -959,7 +959,7 @@ class Model(six.with_metaclass(ModelBase)):
# the list of checks. # the list of checks.
fields_with_class = [(self.__class__, self._meta.local_fields)] fields_with_class = [(self.__class__, self._meta.local_fields)]
for parent_class in self._meta.parents.keys(): for parent_class in self._meta.get_parent_list():
fields_with_class.append((parent_class, parent_class._meta.local_fields)) fields_with_class.append((parent_class, parent_class._meta.local_fields))
for model_class, fields in fields_with_class: for model_class, fields in fields_with_class:

View File

@ -186,3 +186,24 @@ class Base(models.Model):
class SubBase(Base): class SubBase(Base):
sub_id = models.IntegerField(primary_key=True) sub_id = models.IntegerField(primary_key=True)
class GrandParent(models.Model):
first_name = models.CharField(max_length=80)
last_name = models.CharField(max_length=80)
email = models.EmailField(unique=True)
class Meta:
unique_together = ('first_name', 'last_name')
class Parent(GrandParent):
pass
class Child(Parent):
pass
class GrandChild(Child):
pass

View File

@ -2,7 +2,7 @@ from __future__ import unicode_literals
from operator import attrgetter from operator import attrgetter
from django.core.exceptions import FieldError from django.core.exceptions import FieldError, ValidationError
from django.core.management import call_command from django.core.management import call_command
from django.db import connection from django.db import connection
from django.test import TestCase, TransactionTestCase from django.test import TestCase, TransactionTestCase
@ -12,7 +12,7 @@ from django.utils import six
from .models import ( from .models import (
Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, Post, Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, Post,
Restaurant, Student, Supplier, Worker, MixinModel, Restaurant, Student, Supplier, Worker, MixinModel,
Title, Copy, Base, SubBase) Title, Copy, Base, SubBase, GrandParent, GrandChild)
class ModelInheritanceTests(TestCase): class ModelInheritanceTests(TestCase):
@ -423,3 +423,33 @@ class InheritanceSameModelNameTests(TransactionTestCase):
def test_related_name_attribute_exists(self): def test_related_name_attribute_exists(self):
# The Post model doesn't have an attribute called 'attached_%(app_label)s_%(class)s_set'. # The Post model doesn't have an attribute called 'attached_%(app_label)s_%(class)s_set'.
self.assertFalse(hasattr(self.title, 'attached_%(app_label)s_%(class)s_set')) self.assertFalse(hasattr(self.title, 'attached_%(app_label)s_%(class)s_set'))
class InheritanceUniqueTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.grand_parent = GrandParent.objects.create(
email='grand_parent@example.com',
first_name='grand',
last_name='parent',
)
def test_unique(self):
grand_child = GrandChild(
email=self.grand_parent.email,
first_name='grand',
last_name='child',
)
msg = 'Grand parent with this Email already exists.'
with self.assertRaisesMessage(ValidationError, msg):
grand_child.validate_unique()
def test_unique_together(self):
grand_child = GrandChild(
email='grand_child@example.com',
first_name=self.grand_parent.first_name,
last_name=self.grand_parent.last_name,
)
msg = 'Grand parent with this First name and Last name already exists.'
with self.assertRaisesMessage(ValidationError, msg):
grand_child.validate_unique()