Fix BooleanField's allow_null behavior

This commit is contained in:
Rodrigo 2021-11-29 20:27:52 -03:00
parent 580bf45ccf
commit 7af79a0223
2 changed files with 37 additions and 2 deletions

View File

@ -720,6 +720,12 @@ class BooleanField(Field):
}
NULL_VALUES = {'null', 'Null', 'NULL', '', None}
def __init__(self, **kwargs):
if 'allow_null' in kwargs:
self.default_empty_html = None
self.initial = None
super().__init__(**kwargs)
def to_internal_value(self, data):
try:
if data in self.TRUE_VALUES:

View File

@ -363,7 +363,7 @@ class TestBooleanHTMLInput:
def test_empty_html_checkbox(self):
"""
HTML checkboxes do not send any value, but should be treated
as `False` by BooleanField.
as `False` by BooleanField if allow_null=False.
"""
class TestSerializer(serializers.Serializer):
archived = serializers.BooleanField()
@ -375,7 +375,8 @@ class TestBooleanHTMLInput:
def test_empty_html_checkbox_not_required(self):
"""
HTML checkboxes do not send any value, but should be treated
as `False` by BooleanField, even if the field is required=False.
as `False` by BooleanField when the field is required=False
and allow_null=False.
"""
class TestSerializer(serializers.Serializer):
archived = serializers.BooleanField(required=False)
@ -384,6 +385,34 @@ class TestBooleanHTMLInput:
assert serializer.is_valid()
assert serializer.validated_data == {'archived': False}
def test_empty_html_checkbox_allow_null(self):
"""
HTML checkboxes do not send any value and should be treated
as `None` by BooleanField if allow_null is True.
"""
class TestSerializer(serializers.Serializer):
archived = serializers.BooleanField(allow_null=True)
serializer = TestSerializer(data=QueryDict(''))
assert serializer.is_valid()
assert serializer.validated_data == {'archived': None}
def test_empty_html_checkbox_allow_null_with_default(self):
"""
BooleanField should respect default if set and still allow
setting null values.
"""
class TestSerializer(serializers.Serializer):
archived = serializers.BooleanField(allow_null=True, default=True)
serializer = TestSerializer(data=QueryDict(''))
assert serializer.is_valid()
assert serializer.validated_data == {'archived': True}
serializer = TestSerializer(data=QueryDict('archived='))
assert serializer.is_valid()
assert serializer.validated_data == {'archived': None}
class TestHTMLInput:
def test_empty_html_charfield_with_default(self):