Fixed #28867 -- Added system check for a model property that clashes with a related field accessor.

This commit is contained in:
shanghui 2017-12-29 09:22:20 +08:00 committed by Tim Graham
parent fbf647287e
commit cc6bcc6ff5
3 changed files with 42 additions and 3 deletions

View File

@ -1191,9 +1191,10 @@ class Model(metaclass=ModelBase):
*cls._check_long_column_names(),
]
clash_errors = (
cls._check_id_field() +
cls._check_field_name_clashes() +
cls._check_model_name_db_lookup_clashes()
*cls._check_id_field(),
*cls._check_field_name_clashes(),
*cls._check_model_name_db_lookup_clashes(),
*cls._check_property_name_related_field_accessor_clashes(),
)
errors.extend(clash_errors)
# If there are field name clashes, hide consequent column name
@ -1421,6 +1422,26 @@ class Model(metaclass=ModelBase):
)
return errors
@classmethod
def _check_property_name_related_field_accessor_clashes(cls):
errors = []
property_names = cls._meta._property_names
related_field_accessors = (
f.get_attname() for f in cls._meta._get_fields(reverse=False)
if f.is_relation and f.related_model is not None
)
for accessor in related_field_accessors:
if accessor in property_names:
errors.append(
checks.Error(
"The property '%s' clashes with a related field "
"accessor." % accessor,
obj=cls,
id='models.E025',
)
)
return errors
@classmethod
def _check_index_together(cls):
"""Check the value of "index_together" option."""

View File

@ -292,6 +292,8 @@ Models
underscore as it collides with the query lookup syntax.
* **models.E024**: The model name ``<model>`` cannot contain double underscores
as it collides with the query lookup syntax.
* **models.E025**: The property ``<property name>`` clashes with a related
field accessor.
Security
--------

View File

@ -706,6 +706,22 @@ class OtherModelTests(SimpleTestCase):
)
])
def test_property_and_related_field_accessor_clash(self):
class Model(models.Model):
fk = models.ForeignKey('self', models.CASCADE)
@property
def fk_id(self):
pass
self.assertEqual(Model.check(), [
Error(
"The property 'fk_id' clashes with a related field accessor.",
obj=Model,
id='models.E025',
)
])
@override_settings(TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model')
def test_swappable_missing_app_name(self):
class Model(models.Model):