diff options
author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2015-10-05 22:29:23 +0200 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2015-10-06 19:26:00 -0400 |
commit | 4ec96b776ba63f6ad6c9064968178d0814ab9162 (patch) | |
tree | 29582f3889c3cc407450e42d62590455a5abe3d8 | |
parent | 9be9c511cc9f552a34367427aaac3bdc0fdb88fc (diff) | |
download | django-4ec96b776ba63f6ad6c9064968178d0814ab9162.tar.gz |
[1.8.x] Fixed #25503 -- Fixed system check crash on ForeignKey to abstract model.
Backport of 914167abf19d16ac97c0f1f6ae1b08cb377c8f3a from master
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | django/db/models/fields/related.py | 5 | ||||
-rw-r--r-- | docs/releases/1.8.6.txt | 3 | ||||
-rw-r--r-- | tests/invalid_models_tests/test_relative_fields.py | 56 |
4 files changed, 38 insertions, 27 deletions
@@ -434,6 +434,7 @@ answer newbie questions, and generally made Django that much better: Marian Andre <django@andre.sk> Marijn Vriens <marijn@metronomo.cl> Mario Gonzalez <gonzalemario@gmail.com> + Mariusz Felisiak <felisiak.mariusz@gmail.com> Mark Biggers <biggers@utsl.com> mark@junklight.com Mark Lavin <markdlavin@gmail.com> diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 83e2a0aa8f..cdb01cadcb 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1523,6 +1523,9 @@ class ForeignObject(RelatedField): except AttributeError: return [] + if not self.foreign_related_fields: + return [] + has_unique_field = any(rel_field.unique for rel_field in self.foreign_related_fields) if not has_unique_field and len(self.foreign_related_fields) > 1: @@ -1622,7 +1625,7 @@ class ForeignObject(RelatedField): @property def foreign_related_fields(self): - return tuple(rhs_field for lhs_field, rhs_field in self.related_fields) + return tuple(rhs_field for lhs_field, rhs_field in self.related_fields if rhs_field) def get_local_related_value(self, instance): return self.get_instance_value_for_fields(instance, self.local_related_fields) diff --git a/docs/releases/1.8.6.txt b/docs/releases/1.8.6.txt index 15b85a66c8..b972ee0148 100644 --- a/docs/releases/1.8.6.txt +++ b/docs/releases/1.8.6.txt @@ -14,3 +14,6 @@ Bugfixes * Allowed "mode=memory" in SQLite test database name if supported (:ticket:`12118`). + +* Fixed system check crash on ``ForeignKey`` to abstract model + (:ticket:`25503`). diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index 5d174d0c9b..c18fe85538 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -296,25 +296,27 @@ class RelativeFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) def test_foreign_key_to_abstract_model(self): - class Model(models.Model): - foreign_key = models.ForeignKey('AbstractModel') - class AbstractModel(models.Model): class Meta: abstract = True - field = Model._meta.get_field('foreign_key') - errors = field.check() - expected = [ - Error( - ("Field defines a relation with model 'AbstractModel', " - "which is either not installed, or is abstract."), - hint=None, - obj=field, - id='fields.E300', - ), + class Model(models.Model): + rel_string_foreign_key = models.ForeignKey('AbstractModel') + rel_class_foreign_key = models.ForeignKey(AbstractModel) + + fields = [ + Model._meta.get_field('rel_string_foreign_key'), + Model._meta.get_field('rel_class_foreign_key'), ] - self.assertEqual(errors, expected) + expected_error = Error( + "Field defines a relation with model 'AbstractModel', " + "which is either not installed, or is abstract.", + id='fields.E300', + ) + for field in fields: + expected_error.obj = field + errors = field.check() + self.assertEqual(errors, [expected_error]) def test_m2m_to_abstract_model(self): class AbstractModel(models.Model): @@ -322,20 +324,22 @@ class RelativeFieldTests(IsolatedModelsTestCase): abstract = True class Model(models.Model): - m2m = models.ManyToManyField('AbstractModel') + rel_string_m2m = models.ManyToManyField('AbstractModel') + rel_class_m2m = models.ManyToManyField(AbstractModel) - field = Model._meta.get_field('m2m') - errors = field.check(from_model=Model) - expected = [ - Error( - ("Field defines a relation with model 'AbstractModel', " - "which is either not installed, or is abstract."), - hint=None, - obj=field, - id='fields.E300', - ), + fields = [ + Model._meta.get_field('rel_string_m2m'), + Model._meta.get_field('rel_class_m2m'), ] - self.assertEqual(errors, expected) + expected_error = Error( + "Field defines a relation with model 'AbstractModel', " + "which is either not installed, or is abstract.", + id='fields.E300', + ) + for field in fields: + expected_error.obj = field + errors = field.check(from_model=Model) + self.assertEqual(errors, [expected_error]) def test_unique_m2m(self): class Person(models.Model): |