diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 5be2a21bbc..c40dc3fb31 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -184,13 +184,11 @@ def __init__(self, read_only=False, write_only=False, self.style = {} if style is None else style self.allow_null = allow_null - if allow_null and self.default_empty_html 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 - - if default is not empty: - self.default_empty_html = default + if self.default_empty_html is not empty: + if not required: + self.default_empty_html = empty + elif default is not empty: + self.default_empty_html = default if validators is not None: self.validators = validators[:] @@ -562,6 +560,11 @@ def __init__(self, **kwargs): message = self.error_messages['min_length'].format(min_length=min_length) 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): # Test for the empty string here so that it does not get validated, # and so that subclasses do not need to handle it explicitly diff --git a/tests/test_fields.py b/tests/test_fields.py index 7f7af5cc02..04c721d363 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -215,25 +215,47 @@ class MockHTMLDict(dict): 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: - def setup(self): + def test_empty_html_checkbox(self): class TestSerializer(serializers.Serializer): message = serializers.CharField(default='happy') - self.Serializer = TestSerializer - def test_empty_html_checkbox(self): - """ - 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()) + serializer = TestSerializer(data=MockHTMLDict()) assert serializer.is_valid() 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({})) + 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: def setup(self): pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy