Refs #28577 -- Added check for HStoreField to prevent mutable default.
This commit is contained in:
parent
167d98528a
commit
4f7467b690
|
@ -6,15 +6,18 @@ from django.core import exceptions
|
||||||
from django.db.models import Field, TextField, Transform
|
from django.db.models import Field, TextField, Transform
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from .mixins import CheckFieldDefaultMixin
|
||||||
|
|
||||||
__all__ = ['HStoreField']
|
__all__ = ['HStoreField']
|
||||||
|
|
||||||
|
|
||||||
class HStoreField(Field):
|
class HStoreField(CheckFieldDefaultMixin, Field):
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
description = _('Map of strings to strings/nulls')
|
description = _('Map of strings to strings/nulls')
|
||||||
default_error_messages = {
|
default_error_messages = {
|
||||||
'not_a_string': _('The value of "%(key)s" is not a string or null.'),
|
'not_a_string': _('The value of "%(key)s" is not a string or null.'),
|
||||||
}
|
}
|
||||||
|
_default_hint = ('dict', '{}')
|
||||||
|
|
||||||
def db_type(self, connection):
|
def db_type(self, connection):
|
||||||
return 'hstore'
|
return 'hstore'
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.core import exceptions, serializers
|
from django.core import checks, exceptions, serializers
|
||||||
from django.forms import Form
|
from django.forms import Form
|
||||||
from django.test.utils import modify_settings
|
from django.test.utils import isolate_apps, modify_settings
|
||||||
|
|
||||||
from . import PostgreSQLTestCase
|
from . import PostgreSQLTestCase
|
||||||
from .models import HStoreModel
|
from .models import HStoreModel, PostgreSQLModel
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from django.contrib.postgres import forms
|
from django.contrib.postgres import forms
|
||||||
|
@ -190,6 +190,34 @@ class TestQuerying(HStoreTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@isolate_apps('postgres_tests')
|
||||||
|
class TestChecks(PostgreSQLTestCase):
|
||||||
|
|
||||||
|
def test_invalid_default(self):
|
||||||
|
class MyModel(PostgreSQLModel):
|
||||||
|
field = HStoreField(default={})
|
||||||
|
|
||||||
|
model = MyModel()
|
||||||
|
self.assertEqual(model.check(), [
|
||||||
|
checks.Warning(
|
||||||
|
msg=(
|
||||||
|
"HStoreField default should be a callable instead of an "
|
||||||
|
"instance so that it's not shared between all field "
|
||||||
|
"instances."
|
||||||
|
),
|
||||||
|
hint='Use a callable instead, e.g., use `dict` instead of `{}`.',
|
||||||
|
obj=MyModel._meta.get_field('field'),
|
||||||
|
id='postgres.E003',
|
||||||
|
)
|
||||||
|
])
|
||||||
|
|
||||||
|
def test_valid_default(self):
|
||||||
|
class MyModel(PostgreSQLModel):
|
||||||
|
field = HStoreField(default=dict)
|
||||||
|
|
||||||
|
self.assertEqual(MyModel().check(), [])
|
||||||
|
|
||||||
|
|
||||||
class TestSerialization(HStoreTestCase):
|
class TestSerialization(HStoreTestCase):
|
||||||
test_data = json.dumps([{
|
test_data = json.dumps([{
|
||||||
'model': 'postgres_tests.hstoremodel',
|
'model': 'postgres_tests.hstoremodel',
|
||||||
|
|
Loading…
Reference in New Issue