summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsarthakmeh <sarthakmeh03@gmail.com>2015-08-25 23:07:32 +0530
committerTim Graham <timograham@gmail.com>2015-08-25 16:16:54 -0400
commit4bc00defd0cf4de3baf90cad43da62e531987459 (patch)
tree59dba839620536d6a49733a02adbb25bf357d444
parent7efdd40407838dc3c922e0e62e9b4eefabe7de01 (diff)
Fixed #14217 -- Added validation for field name collision when using model inheritance.
-rw-r--r--AUTHORS1
-rw-r--r--django/db/models/base.py8
-rw-r--r--tests/invalid_models_tests/test_models.py19
3 files changed, 27 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 8a13ca9965..bc3576f93b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -629,6 +629,7 @@ answer newbie questions, and generally made Django that much better:
Ryan Niemeyer <https://profiles.google.com/ryan.niemeyer/about>
Sam Newman <http://www.magpiebrain.com/>
Sander Dijkhuis <sander.dijkhuis@gmail.com>
+ Sarthak Mehrish <sarthakmeh03@gmail.com>
schwank@gmail.com
Scot Hacker <shacker@birdhouse.org>
Scott Barr <scott@divisionbyzero.com.au>
diff --git a/django/db/models/base.py b/django/db/models/base.py
index e1d2165e3d..3cbabbc576 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -1334,7 +1334,13 @@ class Model(six.with_metaclass(ModelBase)):
used_fields[f.attname] = f
# Check that fields defined in the model don't clash with fields from
- # parents.
+ # parents, including auto-generated fields like multi-table inheritance
+ # child accessors.
+ for parent in cls._meta.get_parent_list():
+ for f in parent._meta.get_fields():
+ if f not in used_fields:
+ used_fields[f.name] = f
+
for f in cls._meta.local_fields:
clash = used_fields.get(f.name) or used_fields.get(f.attname) or None
# Note that we may detect clash between user-defined non-unique
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py
index a27357a1a6..a93789003f 100644
--- a/tests/invalid_models_tests/test_models.py
+++ b/tests/invalid_models_tests/test_models.py
@@ -436,6 +436,25 @@ class FieldNamesTests(IsolatedModelsTestCase):
class ShadowingFieldsTests(IsolatedModelsTestCase):
+ def test_field_name_clash_with_child_accessor(self):
+ class Parent(models.Model):
+ pass
+
+ class Child(Parent):
+ child = models.CharField(max_length=100)
+
+ errors = Child.check()
+ expected = [
+ Error(
+ "The field 'child' clashes with the field "
+ "'child' from model 'invalid_models_tests.parent'.",
+ hint=None,
+ obj=Child._meta.get_field('child'),
+ id='models.E006',
+ )
+ ]
+ self.assertEqual(errors, expected)
+
def test_multiinheritance_clash(self):
class Mother(models.Model):
clash = models.IntegerField()