[1.9.x] Fixed #25503 -- Fixed system check crash on ForeignKey to abstract model.

Backport of 914167abf1 from master
This commit is contained in:
Mariusz Felisiak 2015-10-05 22:29:23 +02:00 committed by Tim Graham
parent d81b0812d4
commit fbe8930745
4 changed files with 38 additions and 27 deletions

View File

@ -449,6 +449,7 @@ answer newbie questions, and generally made Django that much better:
Marian Andre <django@andre.sk> Marian Andre <django@andre.sk>
Marijn Vriens <marijn@metronomo.cl> Marijn Vriens <marijn@metronomo.cl>
Mario Gonzalez <gonzalemario@gmail.com> Mario Gonzalez <gonzalemario@gmail.com>
Mariusz Felisiak <felisiak.mariusz@gmail.com>
Mark Biggers <biggers@utsl.com> Mark Biggers <biggers@utsl.com>
mark@junklight.com mark@junklight.com
Mark Lavin <markdlavin@gmail.com> Mark Lavin <markdlavin@gmail.com>

View File

@ -470,6 +470,9 @@ class ForeignObject(RelatedField):
except exceptions.FieldDoesNotExist: except exceptions.FieldDoesNotExist:
return [] return []
if not self.foreign_related_fields:
return []
has_unique_field = any(rel_field.unique has_unique_field = any(rel_field.unique
for rel_field in self.foreign_related_fields) for rel_field in self.foreign_related_fields)
if not has_unique_field and len(self.foreign_related_fields) > 1: if not has_unique_field and len(self.foreign_related_fields) > 1:
@ -572,7 +575,7 @@ class ForeignObject(RelatedField):
@property @property
def foreign_related_fields(self): 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): def get_local_related_value(self, instance):
return self.get_instance_value_for_fields(instance, self.local_related_fields) return self.get_instance_value_for_fields(instance, self.local_related_fields)

View File

@ -14,3 +14,6 @@ Bugfixes
* Allowed "mode=memory" in SQLite test database name if supported * Allowed "mode=memory" in SQLite test database name if supported
(:ticket:`12118`). (:ticket:`12118`).
* Fixed system check crash on ``ForeignKey`` to abstract model
(:ticket:`25503`).

View File

@ -386,25 +386,27 @@ class RelativeFieldTests(IsolatedModelsTestCase):
self.assertEqual(errors, expected) self.assertEqual(errors, expected)
def test_foreign_key_to_abstract_model(self): def test_foreign_key_to_abstract_model(self):
class Model(models.Model):
foreign_key = models.ForeignKey('AbstractModel', models.CASCADE)
class AbstractModel(models.Model): class AbstractModel(models.Model):
class Meta: class Meta:
abstract = True abstract = True
field = Model._meta.get_field('foreign_key') class Model(models.Model):
errors = field.check() rel_string_foreign_key = models.ForeignKey('AbstractModel', models.CASCADE)
expected = [ rel_class_foreign_key = models.ForeignKey(AbstractModel, models.CASCADE)
Error(
"Field defines a relation with model 'AbstractModel', " fields = [
"which is either not installed, or is abstract.", Model._meta.get_field('rel_string_foreign_key'),
hint=None, Model._meta.get_field('rel_class_foreign_key'),
obj=field,
id='fields.E300',
),
] ]
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): def test_m2m_to_abstract_model(self):
class AbstractModel(models.Model): class AbstractModel(models.Model):
@ -412,20 +414,22 @@ class RelativeFieldTests(IsolatedModelsTestCase):
abstract = True abstract = True
class Model(models.Model): 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') fields = [
errors = field.check(from_model=Model) Model._meta.get_field('rel_string_m2m'),
expected = [ Model._meta.get_field('rel_class_m2m'),
Error(
"Field defines a relation with model 'AbstractModel', "
"which is either not installed, or is abstract.",
hint=None,
obj=field,
id='fields.E300',
),
] ]
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): def test_unique_m2m(self):
class Person(models.Model): class Person(models.Model):