mirror of
https://github.com/django/django.git
synced 2025-06-04 11:09:13 +00:00
Fixed #27904 -- Added a system check that Field.validators are callable.
This commit is contained in:
parent
75503a823f
commit
a452dddb25
@ -204,6 +204,7 @@ class Field(RegisterLookupMixin):
|
|||||||
errors.extend(self._check_db_index())
|
errors.extend(self._check_db_index())
|
||||||
errors.extend(self._check_null_allowed_for_primary_keys())
|
errors.extend(self._check_null_allowed_for_primary_keys())
|
||||||
errors.extend(self._check_backend_specific_checks(**kwargs))
|
errors.extend(self._check_backend_specific_checks(**kwargs))
|
||||||
|
errors.extend(self._check_validators())
|
||||||
errors.extend(self._check_deprecation_details())
|
errors.extend(self._check_deprecation_details())
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
@ -302,6 +303,25 @@ class Field(RegisterLookupMixin):
|
|||||||
return connections[db].validation.check_field(self, **kwargs)
|
return connections[db].validation.check_field(self, **kwargs)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def _check_validators(self):
|
||||||
|
errors = []
|
||||||
|
for i, validator in enumerate(self.validators):
|
||||||
|
if not callable(validator):
|
||||||
|
errors.append(
|
||||||
|
checks.Error(
|
||||||
|
"All 'validators' must be callable.",
|
||||||
|
hint=(
|
||||||
|
"validators[{i}] ({repr}) isn't a function or "
|
||||||
|
"instance of a validator class.".format(
|
||||||
|
i=i, repr=repr(validator),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
obj=self,
|
||||||
|
id='fields.E008',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return errors
|
||||||
|
|
||||||
def _check_deprecation_details(self):
|
def _check_deprecation_details(self):
|
||||||
if self.system_check_removed_details is not None:
|
if self.system_check_removed_details is not None:
|
||||||
return [
|
return [
|
||||||
|
@ -154,6 +154,7 @@ Model fields
|
|||||||
human readable name)`` tuples.
|
human readable name)`` tuples.
|
||||||
* **fields.E006**: ``db_index`` must be ``None``, ``True`` or ``False``.
|
* **fields.E006**: ``db_index`` must be ``None``, ``True`` or ``False``.
|
||||||
* **fields.E007**: Primary keys must not have ``null=True``.
|
* **fields.E007**: Primary keys must not have ``null=True``.
|
||||||
|
* **fields.E008**: All ``validators`` must be callable.
|
||||||
* **fields.E100**: ``AutoField``\s must set primary_key=True.
|
* **fields.E100**: ``AutoField``\s must set primary_key=True.
|
||||||
* **fields.E110**: ``BooleanField``\s do not accept null values.
|
* **fields.E110**: ``BooleanField``\s do not accept null values.
|
||||||
* **fields.E120**: ``CharField``\s must define a ``max_length`` attribute.
|
* **fields.E120**: ``CharField``\s must define a ``max_length`` attribute.
|
||||||
|
@ -205,6 +205,23 @@ class CharFieldTests(TestCase):
|
|||||||
]
|
]
|
||||||
self.assertEqual(errors, expected)
|
self.assertEqual(errors, expected)
|
||||||
|
|
||||||
|
def test_bad_validators(self):
|
||||||
|
class Model(models.Model):
|
||||||
|
field = models.CharField(max_length=10, validators=[True])
|
||||||
|
|
||||||
|
field = Model._meta.get_field('field')
|
||||||
|
self.assertEqual(field.check(), [
|
||||||
|
Error(
|
||||||
|
"All 'validators' must be callable.",
|
||||||
|
hint=(
|
||||||
|
"validators[0] (True) isn't a function or instance of a "
|
||||||
|
"validator class."
|
||||||
|
),
|
||||||
|
obj=field,
|
||||||
|
id='fields.E008',
|
||||||
|
),
|
||||||
|
])
|
||||||
|
|
||||||
@unittest.skipUnless(connection.vendor == 'mysql',
|
@unittest.skipUnless(connection.vendor == 'mysql',
|
||||||
"Test valid only for MySQL")
|
"Test valid only for MySQL")
|
||||||
def test_too_long_char_field_under_mysql(self):
|
def test_too_long_char_field_under_mysql(self):
|
||||||
|
@ -102,7 +102,7 @@ class RelativeFieldTests(SimpleTestCase):
|
|||||||
m2m = models.ManyToManyField(
|
m2m = models.ManyToManyField(
|
||||||
Model,
|
Model,
|
||||||
null=True,
|
null=True,
|
||||||
validators=[''],
|
validators=[lambda x: x],
|
||||||
limit_choices_to={'name': 'test_name'},
|
limit_choices_to={'name': 'test_name'},
|
||||||
through='ThroughModel',
|
through='ThroughModel',
|
||||||
through_fields=('modelm2m', 'model'),
|
through_fields=('modelm2m', 'model'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user