Add HStoreField

This commit is contained in:
Ryan P Kilby 2017-12-05 00:35:48 -05:00
parent 7df7e252f6
commit 6fda742b89
4 changed files with 43 additions and 8 deletions

View File

@ -1684,6 +1684,10 @@ class DictField(Field):
} }
class HStoreField(DictField):
child = CharField(allow_blank=True, allow_null=True)
class JSONField(Field): class JSONField(Field):
default_error_messages = { default_error_messages = {
'invalid': _('Value must be valid JSON.') 'invalid': _('Value must be valid JSON.')

View File

@ -54,9 +54,9 @@ from rest_framework.validators import (
from rest_framework.fields import ( # NOQA # isort:skip from rest_framework.fields import ( # NOQA # isort:skip
BooleanField, CharField, ChoiceField, DateField, DateTimeField, DecimalField, BooleanField, CharField, ChoiceField, DateField, DateTimeField, DecimalField,
DictField, DurationField, EmailField, Field, FileField, FilePathField, FloatField, DictField, DurationField, EmailField, Field, FileField, FilePathField, FloatField,
HiddenField, IPAddressField, ImageField, IntegerField, JSONField, ListField, HiddenField, HStoreField, IPAddressField, ImageField, IntegerField, JSONField,
ModelField, MultipleChoiceField, NullBooleanField, ReadOnlyField, RegexField, ListField, ModelField, MultipleChoiceField, NullBooleanField, ReadOnlyField,
SerializerMethodField, SlugField, TimeField, URLField, UUIDField, RegexField, SerializerMethodField, SlugField, TimeField, URLField, UUIDField,
) )
from rest_framework.relations import ( # NOQA # isort:skip from rest_framework.relations import ( # NOQA # isort:skip
HyperlinkedIdentityField, HyperlinkedRelatedField, ManyRelatedField, HyperlinkedIdentityField, HyperlinkedRelatedField, ManyRelatedField,
@ -1541,10 +1541,7 @@ if hasattr(models, 'IPAddressField'):
ModelSerializer.serializer_field_mapping[models.IPAddressField] = IPAddressField ModelSerializer.serializer_field_mapping[models.IPAddressField] = IPAddressField
if postgres_fields: if postgres_fields:
class CharMappingField(DictField): ModelSerializer.serializer_field_mapping[postgres_fields.HStoreField] = HStoreField
child = CharField(allow_blank=True)
ModelSerializer.serializer_field_mapping[postgres_fields.HStoreField] = CharMappingField
ModelSerializer.serializer_field_mapping[postgres_fields.ArrayField] = ListField ModelSerializer.serializer_field_mapping[postgres_fields.ArrayField] = ListField
ModelSerializer.serializer_field_mapping[postgres_fields.JSONField] = JSONField ModelSerializer.serializer_field_mapping[postgres_fields.JSONField] = JSONField

View File

@ -1897,6 +1897,40 @@ class TestUnvalidatedDictField(FieldValues):
field = serializers.DictField() field = serializers.DictField()
class TestHStoreField(FieldValues):
"""
Values for `ListField` with CharField as child.
"""
valid_inputs = [
({'a': 1, 'b': '2', 3: 3}, {'a': '1', 'b': '2', '3': '3'}),
({'a': 1, 'b': None}, {'a': '1', 'b': None}),
]
invalid_inputs = [
('not a dict', ['Expected a dictionary of items but got type "str".']),
]
outputs = [
({'a': 1, 'b': '2', 3: 3}, {'a': '1', 'b': '2', '3': '3'}),
]
field = serializers.HStoreField()
def test_no_source_on_child(self):
with pytest.raises(AssertionError) as exc_info:
serializers.HStoreField(child=serializers.CharField(source='other'))
assert str(exc_info.value) == (
"The `source` argument is not meaningful when applied to a `child=` field. "
"Remove `source=` from the field declaration."
)
def test_allow_null(self):
"""
If `allow_null=True` then `None` is a valid input.
"""
field = serializers.HStoreField(allow_null=True)
output = field.run_validation(None)
assert output is None
class TestJSONField(FieldValues): class TestJSONField(FieldValues):
""" """
Values for `JSONField`. Values for `JSONField`.

View File

@ -392,7 +392,7 @@ class TestPosgresFieldsMapping(TestCase):
expected = dedent(""" expected = dedent("""
TestSerializer(): TestSerializer():
hstore_field = CharMappingField() hstore_field = HStoreField()
""") """)
self.assertEqual(unicode_repr(TestSerializer()), expected) self.assertEqual(unicode_repr(TestSerializer()), expected)