Fixed #15321 -- Honored ancestors unique checks.
Thanks to Tim for the review.
This commit is contained in:
parent
1fc458b5a3
commit
79f27f2b61
|
@ -938,7 +938,7 @@ class Model(six.with_metaclass(ModelBase)):
|
|||
unique_checks = []
|
||||
|
||||
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:
|
||||
unique_togethers.append((parent_class, parent_class._meta.unique_together))
|
||||
|
||||
|
@ -958,7 +958,7 @@ class Model(six.with_metaclass(ModelBase)):
|
|||
# the list of checks.
|
||||
|
||||
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))
|
||||
|
||||
for model_class, fields in fields_with_class:
|
||||
|
|
|
@ -186,3 +186,24 @@ class Base(models.Model):
|
|||
|
||||
class SubBase(Base):
|
||||
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
|
||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import unicode_literals
|
|||
|
||||
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.db import connection
|
||||
from django.test import TestCase, TransactionTestCase
|
||||
|
@ -12,7 +12,7 @@ from django.utils import six
|
|||
from .models import (
|
||||
Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, Post,
|
||||
Restaurant, Student, Supplier, Worker, MixinModel,
|
||||
Title, Copy, Base, SubBase)
|
||||
Title, Copy, Base, SubBase, GrandParent, GrandChild)
|
||||
|
||||
|
||||
class ModelInheritanceTests(TestCase):
|
||||
|
@ -423,3 +423,33 @@ class InheritanceSameModelNameTests(TransactionTestCase):
|
|||
def test_related_name_attribute_exists(self):
|
||||
# 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'))
|
||||
|
||||
|
||||
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()
|
||||
|
|
Loading…
Reference in New Issue