diff --git a/django/contrib/postgres/fields/array.py b/django/contrib/postgres/fields/array.py index 1180795e8f..f8ce7911ef 100644 --- a/django/contrib/postgres/fields/array.py +++ b/django/contrib/postgres/fields/array.py @@ -5,11 +5,11 @@ from django.contrib.postgres.forms import SimpleArrayField from django.contrib.postgres.validators import ArrayMaxLengthValidator from django.core import checks, exceptions from django.db.models import Field, IntegerField, Transform +from django.db.models.fields.mixins import CheckFieldDefaultMixin from django.db.models.lookups import Exact, In from django.utils.translation import gettext_lazy as _ from ..utils import prefix_validation_error -from .mixins import CheckFieldDefaultMixin from .utils import AttributeSetter __all__ = ['ArrayField'] diff --git a/django/contrib/postgres/fields/hstore.py b/django/contrib/postgres/fields/hstore.py index 0889f600a5..2ec5766041 100644 --- a/django/contrib/postgres/fields/hstore.py +++ b/django/contrib/postgres/fields/hstore.py @@ -4,10 +4,9 @@ from django.contrib.postgres import forms, lookups from django.contrib.postgres.fields.array import ArrayField from django.core import exceptions from django.db.models import Field, TextField, Transform +from django.db.models.fields.mixins import CheckFieldDefaultMixin from django.utils.translation import gettext_lazy as _ -from .mixins import CheckFieldDefaultMixin - __all__ = ['HStoreField'] diff --git a/django/contrib/postgres/fields/jsonb.py b/django/contrib/postgres/fields/jsonb.py index 30c48a6018..c402dd19d8 100644 --- a/django/contrib/postgres/fields/jsonb.py +++ b/django/contrib/postgres/fields/jsonb.py @@ -7,10 +7,9 @@ from django.core import exceptions from django.db.models import ( Field, TextField, Transform, lookups as builtin_lookups, ) +from django.db.models.fields.mixins import CheckFieldDefaultMixin from django.utils.translation import gettext_lazy as _ -from .mixins import CheckFieldDefaultMixin - __all__ = ['JSONField'] diff --git a/django/contrib/postgres/fields/mixins.py b/django/contrib/postgres/fields/mixins.py deleted file mode 100644 index 254b80c4a2..0000000000 --- a/django/contrib/postgres/fields/mixins.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.core import checks - - -class CheckFieldDefaultMixin: - _default_hint = ('', '') - - def _check_default(self): - if self.has_default() and self.default is not None and not callable(self.default): - return [ - checks.Warning( - "%s default should be a callable instead of an instance so " - "that it's not shared between all field instances." % ( - self.__class__.__name__, - ), - hint=( - 'Use a callable instead, e.g., use `%s` instead of ' - '`%s`.' % self._default_hint - ), - obj=self, - id='postgres.E003', - ) - ] - else: - return [] - - def check(self, **kwargs): - errors = super().check(**kwargs) - errors.extend(self._check_default()) - return errors diff --git a/django/db/models/fields/mixins.py b/django/db/models/fields/mixins.py index c6dbc4ec5e..3afa8d9304 100644 --- a/django/db/models/fields/mixins.py +++ b/django/db/models/fields/mixins.py @@ -1,3 +1,5 @@ +from django.core import checks + NOT_PROVIDED = object() @@ -24,3 +26,31 @@ class FieldCacheMixin: def delete_cached_value(self, instance): del instance._state.fields_cache[self.get_cache_name()] + + +class CheckFieldDefaultMixin: + _default_hint = ('', '') + + def _check_default(self): + if self.has_default() and self.default is not None and not callable(self.default): + return [ + checks.Warning( + "%s default should be a callable instead of an instance " + "so that it's not shared between all field instances." % ( + self.__class__.__name__, + ), + hint=( + 'Use a callable instead, e.g., use `%s` instead of ' + '`%s`.' % self._default_hint + ), + obj=self, + id='fields.E010', + ) + ] + else: + return [] + + def check(self, **kwargs): + errors = super().check(**kwargs) + errors.extend(self._check_default()) + return errors diff --git a/docs/ref/checks.txt b/docs/ref/checks.txt index 9bcba596fa..9c5b86eafd 100644 --- a/docs/ref/checks.txt +++ b/docs/ref/checks.txt @@ -140,6 +140,8 @@ Model fields * **fields.E008**: All ``validators`` must be callable. * **fields.E009**: ``max_length`` is too small to fit the longest value in ``choices`` (```` characters). +* **fields.E010**: ```` default should be a callable instead of an + instance so that it's not shared between all field instances. * **fields.E100**: ``AutoField``\s must set primary_key=True. * **fields.E110**: ``BooleanField``\s do not accept null values. *This check appeared before support for null values was added in Django 2.1.* @@ -747,7 +749,8 @@ fields: * **postgres.E001**: Base field for array has errors: ... * **postgres.E002**: Base field for array cannot be a related field. * **postgres.E003**: ```` default should be a callable instead of an - instance so that it's not shared between all field instances. + instance so that it's not shared between all field instances. *This check was + changed to* ``fields.E010`` *in Django 3.1*. ``sites`` --------- diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py index 42885e61f6..3f54110447 100644 --- a/tests/postgres_tests/test_array.py +++ b/tests/postgres_tests/test_array.py @@ -551,7 +551,7 @@ class TestChecks(PostgreSQLSimpleTestCase): ), hint='Use a callable instead, e.g., use `list` instead of `[]`.', obj=MyModel._meta.get_field('field'), - id='postgres.E003', + id='fields.E010', ) ]) diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py index a3fae1ec66..dbb1357c41 100644 --- a/tests/postgres_tests/test_hstore.py +++ b/tests/postgres_tests/test_hstore.py @@ -231,7 +231,7 @@ class TestChecks(PostgreSQLSimpleTestCase): ), hint='Use a callable instead, e.g., use `dict` instead of `{}`.', obj=MyModel._meta.get_field('field'), - id='postgres.E003', + id='fields.E010', ) ]) diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py index 956304d6f5..0ffa05f981 100644 --- a/tests/postgres_tests/test_json.py +++ b/tests/postgres_tests/test_json.py @@ -429,7 +429,7 @@ class TestChecks(PostgreSQLSimpleTestCase): ), hint='Use a callable instead, e.g., use `dict` instead of `{}`.', obj=MyModel._meta.get_field('field'), - id='postgres.E003', + id='fields.E010', ) ])