mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 09:36:49 +03:00
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
This commit is contained in:
parent
5f1f2b1003
commit
fc6cbb5b26
|
@ -674,10 +674,7 @@ class BooleanField(Field):
|
||||||
'0', 0, 0.0,
|
'0', 0, 0.0,
|
||||||
False
|
False
|
||||||
}
|
}
|
||||||
|
NULL_VALUES = {'null', 'Null', 'NULL', '', None}
|
||||||
def __init__(self, **kwargs):
|
|
||||||
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option. Use `NullBooleanField` instead.'
|
|
||||||
super(BooleanField, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
try:
|
try:
|
||||||
|
@ -685,6 +682,8 @@ class BooleanField(Field):
|
||||||
return True
|
return True
|
||||||
elif data in self.FALSE_VALUES:
|
elif data in self.FALSE_VALUES:
|
||||||
return False
|
return False
|
||||||
|
elif data in self.NULL_VALUES and self.allow_null:
|
||||||
|
return None
|
||||||
except TypeError: # Input is an unhashable type
|
except TypeError: # Input is an unhashable type
|
||||||
pass
|
pass
|
||||||
self.fail('invalid', input=data)
|
self.fail('invalid', input=data)
|
||||||
|
@ -694,6 +693,8 @@ class BooleanField(Field):
|
||||||
return True
|
return True
|
||||||
elif value in self.FALSE_VALUES:
|
elif value in self.FALSE_VALUES:
|
||||||
return False
|
return False
|
||||||
|
if value in self.NULL_VALUES and self.allow_null:
|
||||||
|
return None
|
||||||
return bool(value)
|
return bool(value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -718,7 +719,7 @@ class NullBooleanField(Field):
|
||||||
'0', 0, 0.0,
|
'0', 0, 0.0,
|
||||||
False
|
False
|
||||||
}
|
}
|
||||||
NULL_VALUES = {'n', 'N', 'null', 'Null', 'NULL', '', None}
|
NULL_VALUES = {'null', 'Null', 'NULL', '', None}
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'
|
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'
|
||||||
|
|
|
@ -657,7 +657,7 @@ class TestBooleanField(FieldValues):
|
||||||
|
|
||||||
class TestNullBooleanField(TestBooleanField):
|
class TestNullBooleanField(TestBooleanField):
|
||||||
"""
|
"""
|
||||||
Valid and invalid values for `BooleanField`.
|
Valid and invalid values for `NullBooleanField`.
|
||||||
"""
|
"""
|
||||||
valid_inputs = {
|
valid_inputs = {
|
||||||
'true': True,
|
'true': True,
|
||||||
|
@ -682,6 +682,16 @@ class TestNullBooleanField(TestBooleanField):
|
||||||
field = serializers.NullBooleanField()
|
field = serializers.NullBooleanField()
|
||||||
|
|
||||||
|
|
||||||
|
class TestNullableBooleanField(TestNullBooleanField):
|
||||||
|
"""
|
||||||
|
Valid and invalid values for `BooleanField` when `allow_null=True`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def field(self):
|
||||||
|
return serializers.BooleanField(allow_null=True)
|
||||||
|
|
||||||
|
|
||||||
# String types...
|
# String types...
|
||||||
|
|
||||||
class TestCharField(FieldValues):
|
class TestCharField(FieldValues):
|
||||||
|
|
|
@ -12,6 +12,7 @@ import decimal
|
||||||
import sys
|
import sys
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
import django
|
||||||
import pytest
|
import pytest
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.validators import (
|
from django.core.validators import (
|
||||||
|
@ -220,6 +221,25 @@ class TestRegularFieldMappings(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(unicode_repr(TestSerializer()), expected)
|
self.assertEqual(unicode_repr(TestSerializer()), expected)
|
||||||
|
|
||||||
|
# merge this into test_regular_fields / RegularFieldsModel when
|
||||||
|
# Django 2.1 is the minimum supported version
|
||||||
|
@pytest.mark.skipif(django.VERSION < (2, 1), reason='Django version < 2.1')
|
||||||
|
def test_nullable_boolean_field(self):
|
||||||
|
class NullableBooleanModel(models.Model):
|
||||||
|
field = models.BooleanField(null=True, default=False)
|
||||||
|
|
||||||
|
class NullableBooleanSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = NullableBooleanModel
|
||||||
|
fields = ['field']
|
||||||
|
|
||||||
|
expected = dedent("""
|
||||||
|
NullableBooleanSerializer():
|
||||||
|
field = BooleanField(allow_null=True, required=False)
|
||||||
|
""")
|
||||||
|
|
||||||
|
self.assertEqual(unicode_repr(NullableBooleanSerializer()), expected)
|
||||||
|
|
||||||
def test_method_field(self):
|
def test_method_field(self):
|
||||||
"""
|
"""
|
||||||
Properties and methods on the model should be allowed as `Meta.fields`
|
Properties and methods on the model should be allowed as `Meta.fields`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user