Skip to content

Commit fc6cbb5

Browse files
rpkilbytomchristie
authored andcommitted
Allow nullable BooleanField in Django 2.1 (#6183)
* Add tests for BooleanField when nullable * Allow nullable BooleanField in Django 2.1 * Drop 'BooleanField.allow_null' check * Remove conflicting false/null values
1 parent 5f1f2b1 commit fc6cbb5

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

rest_framework/fields.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -674,17 +674,16 @@ class BooleanField(Field):
674674
'0', 0, 0.0,
675675
False
676676
}
677-
678-
def __init__(self, **kwargs):
679-
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option. Use `NullBooleanField` instead.'
680-
super(BooleanField, self).__init__(**kwargs)
677+
NULL_VALUES = {'null', 'Null', 'NULL', '', None}
681678

682679
def to_internal_value(self, data):
683680
try:
684681
if data in self.TRUE_VALUES:
685682
return True
686683
elif data in self.FALSE_VALUES:
687684
return False
685+
elif data in self.NULL_VALUES and self.allow_null:
686+
return None
688687
except TypeError: # Input is an unhashable type
689688
pass
690689
self.fail('invalid', input=data)
@@ -694,6 +693,8 @@ def to_representation(self, value):
694693
return True
695694
elif value in self.FALSE_VALUES:
696695
return False
696+
if value in self.NULL_VALUES and self.allow_null:
697+
return None
697698
return bool(value)
698699

699700

@@ -718,7 +719,7 @@ class NullBooleanField(Field):
718719
'0', 0, 0.0,
719720
False
720721
}
721-
NULL_VALUES = {'n', 'N', 'null', 'Null', 'NULL', '', None}
722+
NULL_VALUES = {'null', 'Null', 'NULL', '', None}
722723

723724
def __init__(self, **kwargs):
724725
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'

tests/test_fields.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,7 @@ def test_disallow_unhashable_collection_types(self):
657657

658658
class TestNullBooleanField(TestBooleanField):
659659
"""
660-
Valid and invalid values for `BooleanField`.
660+
Valid and invalid values for `NullBooleanField`.
661661
"""
662662
valid_inputs = {
663663
'true': True,
@@ -682,6 +682,16 @@ class TestNullBooleanField(TestBooleanField):
682682
field = serializers.NullBooleanField()
683683

684684

685+
class TestNullableBooleanField(TestNullBooleanField):
686+
"""
687+
Valid and invalid values for `BooleanField` when `allow_null=True`.
688+
"""
689+
690+
@property
691+
def field(self):
692+
return serializers.BooleanField(allow_null=True)
693+
694+
685695
# String types...
686696

687697
class TestCharField(FieldValues):

tests/test_model_serializer.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import sys
1313
from collections import OrderedDict
1414

15+
import django
1516
import pytest
1617
from django.core.exceptions import ImproperlyConfigured
1718
from django.core.validators import (
@@ -220,6 +221,25 @@ class Meta:
220221
)
221222
self.assertEqual(unicode_repr(TestSerializer()), expected)
222223

224+
# merge this into test_regular_fields / RegularFieldsModel when
225+
# Django 2.1 is the minimum supported version
226+
@pytest.mark.skipif(django.VERSION < (2, 1), reason='Django version < 2.1')
227+
def test_nullable_boolean_field(self):
228+
class NullableBooleanModel(models.Model):
229+
field = models.BooleanField(null=True, default=False)
230+
231+
class NullableBooleanSerializer(serializers.ModelSerializer):
232+
class Meta:
233+
model = NullableBooleanModel
234+
fields = ['field']
235+
236+
expected = dedent("""
237+
NullableBooleanSerializer():
238+
field = BooleanField(allow_null=True, required=False)
239+
""")
240+
241+
self.assertEqual(unicode_repr(NullableBooleanSerializer()), expected)
242+
223243
def test_method_field(self):
224244
"""
225245
Properties and methods on the model should be allowed as `Meta.fields`

0 commit comments

Comments
 (0)
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