mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-02 20:54:42 +03:00
Fixes for behavior with empty HTML fields.
This commit is contained in:
parent
b8af83493f
commit
87ac64e41b
|
@ -184,13 +184,11 @@ class Field(object):
|
||||||
self.style = {} if style is None else style
|
self.style = {} if style is None else style
|
||||||
self.allow_null = allow_null
|
self.allow_null = allow_null
|
||||||
|
|
||||||
if allow_null and self.default_empty_html is empty:
|
if self.default_empty_html is not empty:
|
||||||
# HTML input cannot represent `None` values, so we need to
|
if not required:
|
||||||
# forcibly coerce empty HTML values to `None` if `allow_null=True`.
|
self.default_empty_html = empty
|
||||||
self.default_empty_html = None
|
elif default is not empty:
|
||||||
|
self.default_empty_html = default
|
||||||
if default is not empty:
|
|
||||||
self.default_empty_html = default
|
|
||||||
|
|
||||||
if validators is not None:
|
if validators is not None:
|
||||||
self.validators = validators[:]
|
self.validators = validators[:]
|
||||||
|
@ -562,6 +560,11 @@ class CharField(Field):
|
||||||
message = self.error_messages['min_length'].format(min_length=min_length)
|
message = self.error_messages['min_length'].format(min_length=min_length)
|
||||||
self.validators.append(MinLengthValidator(min_length, message=message))
|
self.validators.append(MinLengthValidator(min_length, message=message))
|
||||||
|
|
||||||
|
if self.allow_null and (not self.allow_blank) and (self.default is empty):
|
||||||
|
# HTML input cannot represent `None` values, so we need to
|
||||||
|
# forcibly coerce empty HTML values to `None` if `allow_null=True`.
|
||||||
|
self.default_empty_html = None
|
||||||
|
|
||||||
def run_validation(self, data=empty):
|
def run_validation(self, data=empty):
|
||||||
# Test for the empty string here so that it does not get validated,
|
# Test for the empty string here so that it does not get validated,
|
||||||
# and so that subclasses do not need to handle it explicitly
|
# and so that subclasses do not need to handle it explicitly
|
||||||
|
|
|
@ -215,25 +215,49 @@ class TestBooleanHTMLInput:
|
||||||
assert serializer.validated_data == {'archived': False}
|
assert serializer.validated_data == {'archived': False}
|
||||||
|
|
||||||
|
|
||||||
|
class MockHTMLDict(dict):
|
||||||
|
"""
|
||||||
|
This class mocks up a dictionary like object, that behaves
|
||||||
|
as if it was returned for multipart or urlencoded data.
|
||||||
|
"""
|
||||||
|
getlist = None
|
||||||
|
|
||||||
|
|
||||||
class TestCharHTMLInput:
|
class TestCharHTMLInput:
|
||||||
def setup(self):
|
def test_empty_html_checkbox(self):
|
||||||
class TestSerializer(serializers.Serializer):
|
class TestSerializer(serializers.Serializer):
|
||||||
message = serializers.CharField(default='happy')
|
message = serializers.CharField(default='happy')
|
||||||
self.Serializer = TestSerializer
|
|
||||||
|
|
||||||
def test_empty_html_checkbox(self):
|
serializer = TestSerializer(data=MockHTMLDict())
|
||||||
"""
|
|
||||||
HTML checkboxes do not send any value, but should be treated
|
|
||||||
as `False` by BooleanField.
|
|
||||||
"""
|
|
||||||
# This class mocks up a dictionary like object, that behaves
|
|
||||||
# as if it was returned for multipart or urlencoded data.
|
|
||||||
class MockHTMLDict(dict):
|
|
||||||
getlist = None
|
|
||||||
serializer = self.Serializer(data=MockHTMLDict())
|
|
||||||
assert serializer.is_valid()
|
assert serializer.is_valid()
|
||||||
assert serializer.validated_data == {'message': 'happy'}
|
assert serializer.validated_data == {'message': 'happy'}
|
||||||
|
|
||||||
|
def test_empty_html_checkbox_allow_null(self):
|
||||||
|
class TestSerializer(serializers.Serializer):
|
||||||
|
message = serializers.CharField(allow_null=True)
|
||||||
|
|
||||||
|
serializer = TestSerializer(data=MockHTMLDict())
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert serializer.validated_data == {'message': None}
|
||||||
|
|
||||||
|
def test_empty_html_checkbox_allow_null_allow_blank(self):
|
||||||
|
class TestSerializer(serializers.Serializer):
|
||||||
|
message = serializers.CharField(allow_null=True, allow_blank=True)
|
||||||
|
|
||||||
|
serializer = TestSerializer(data=MockHTMLDict({}))
|
||||||
|
print serializer.is_valid()
|
||||||
|
print serializer.errors
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert serializer.validated_data == {'message': ''}
|
||||||
|
|
||||||
|
def test_empty_html_required_false(self):
|
||||||
|
class TestSerializer(serializers.Serializer):
|
||||||
|
message = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
serializer = TestSerializer(data=MockHTMLDict())
|
||||||
|
assert serializer.is_valid()
|
||||||
|
assert serializer.validated_data == {}
|
||||||
|
|
||||||
|
|
||||||
class TestCreateOnlyDefault:
|
class TestCreateOnlyDefault:
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user