Fixed #25503 -- Fixed system check crash on ForeignKey to abstract model.
This commit is contained in:
parent
3f766d44c5
commit
914167abf1
1
AUTHORS
1
AUTHORS
|
@ -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>
|
||||||
|
|
|
@ -461,6 +461,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:
|
||||||
|
@ -563,7 +566,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)
|
||||||
|
|
|
@ -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`).
|
||||||
|
|
|
@ -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(
|
|
||||||
|
fields = [
|
||||||
|
Model._meta.get_field('rel_string_foreign_key'),
|
||||||
|
Model._meta.get_field('rel_class_foreign_key'),
|
||||||
|
]
|
||||||
|
expected_error = Error(
|
||||||
"Field defines a relation with model 'AbstractModel', "
|
"Field defines a relation with model 'AbstractModel', "
|
||||||
"which is either not installed, or is abstract.",
|
"which is either not installed, or is abstract.",
|
||||||
hint=None,
|
|
||||||
obj=field,
|
|
||||||
id='fields.E300',
|
id='fields.E300',
|
||||||
),
|
)
|
||||||
]
|
for field in fields:
|
||||||
self.assertEqual(errors, expected)
|
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(
|
]
|
||||||
|
expected_error = Error(
|
||||||
"Field defines a relation with model 'AbstractModel', "
|
"Field defines a relation with model 'AbstractModel', "
|
||||||
"which is either not installed, or is abstract.",
|
"which is either not installed, or is abstract.",
|
||||||
hint=None,
|
|
||||||
obj=field,
|
|
||||||
id='fields.E300',
|
id='fields.E300',
|
||||||
),
|
)
|
||||||
]
|
for field in fields:
|
||||||
self.assertEqual(errors, expected)
|
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):
|
||||||
|
|
Loading…
Reference in New Issue