summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/base.py4
-rw-r--r--tests/model_inheritance/models.py21
-rw-r--r--tests/model_inheritance/tests.py34
3 files changed, 55 insertions, 4 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index f91fb3f9b6..4f00a6f0ce 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -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:
diff --git a/tests/model_inheritance/models.py b/tests/model_inheritance/models.py
index 3245c71232..af28159757 100644
--- a/tests/model_inheritance/models.py
+++ b/tests/model_inheritance/models.py
@@ -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
diff --git a/tests/model_inheritance/tests.py b/tests/model_inheritance/tests.py
index e207fe9a84..a732464e69 100644
--- a/tests/model_inheritance/tests.py
+++ b/tests/model_inheritance/tests.py
@@ -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()