mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 00:04:16 +03:00
NullBooleanField
This commit is contained in:
parent
f22d0afc3d
commit
0404f09a7e
|
@ -289,6 +289,10 @@ class BooleanField(Field):
|
||||||
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
||||||
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
||||||
|
|
||||||
|
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):
|
||||||
if data in self.TRUE_VALUES:
|
if data in self.TRUE_VALUES:
|
||||||
return True
|
return True
|
||||||
|
@ -297,7 +301,38 @@ class BooleanField(Field):
|
||||||
self.fail('invalid', input=data)
|
self.fail('invalid', input=data)
|
||||||
|
|
||||||
def to_representation(self, value):
|
def to_representation(self, value):
|
||||||
if value is None:
|
if value in self.TRUE_VALUES:
|
||||||
|
return True
|
||||||
|
elif value in self.FALSE_VALUES:
|
||||||
|
return False
|
||||||
|
return bool(value)
|
||||||
|
|
||||||
|
|
||||||
|
class NullBooleanField(Field):
|
||||||
|
default_error_messages = {
|
||||||
|
'invalid': _('`{input}` is not a valid boolean.')
|
||||||
|
}
|
||||||
|
default_empty_html = None
|
||||||
|
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
|
||||||
|
FALSE_VALUES = set(('f', 'F', 'false', 'False', 'FALSE', '0', 0, 0.0, False))
|
||||||
|
NULL_VALUES = set(('n', 'N', 'null', 'Null', 'NULL', '', None))
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'
|
||||||
|
kwargs['allow_null'] = True
|
||||||
|
super(NullBooleanField, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
if data in self.TRUE_VALUES:
|
||||||
|
return True
|
||||||
|
elif data in self.FALSE_VALUES:
|
||||||
|
return False
|
||||||
|
elif data in self.NULL_VALUES:
|
||||||
|
return None
|
||||||
|
self.fail('invalid', input=data)
|
||||||
|
|
||||||
|
def to_representation(self, value):
|
||||||
|
if value in self.NULL_VALUES:
|
||||||
return None
|
return None
|
||||||
if value in self.TRUE_VALUES:
|
if value in self.TRUE_VALUES:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -333,7 +333,7 @@ class ModelSerializer(Serializer):
|
||||||
models.FloatField: FloatField,
|
models.FloatField: FloatField,
|
||||||
models.ImageField: ImageField,
|
models.ImageField: ImageField,
|
||||||
models.IntegerField: IntegerField,
|
models.IntegerField: IntegerField,
|
||||||
models.NullBooleanField: BooleanField,
|
models.NullBooleanField: NullBooleanField,
|
||||||
models.PositiveIntegerField: IntegerField,
|
models.PositiveIntegerField: IntegerField,
|
||||||
models.PositiveSmallIntegerField: IntegerField,
|
models.PositiveSmallIntegerField: IntegerField,
|
||||||
models.SlugField: SlugField,
|
models.SlugField: SlugField,
|
||||||
|
|
|
@ -74,7 +74,7 @@ def get_field_kwargs(field_name, model_field):
|
||||||
kwargs['choices'] = model_field.flatchoices
|
kwargs['choices'] = model_field.flatchoices
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
if model_field.null:
|
if model_field.null and not isinstance(model_field, models.NullBooleanField):
|
||||||
kwargs['allow_null'] = True
|
kwargs['allow_null'] = True
|
||||||
|
|
||||||
if model_field.blank:
|
if model_field.blank:
|
||||||
|
|
|
@ -124,7 +124,8 @@ class TestBooleanField(FieldValues):
|
||||||
False: False,
|
False: False,
|
||||||
}
|
}
|
||||||
invalid_inputs = {
|
invalid_inputs = {
|
||||||
'foo': ['`foo` is not a valid boolean.']
|
'foo': ['`foo` is not a valid boolean.'],
|
||||||
|
None: ['This field may not be null.']
|
||||||
}
|
}
|
||||||
outputs = {
|
outputs = {
|
||||||
'true': True,
|
'true': True,
|
||||||
|
@ -140,6 +141,32 @@ class TestBooleanField(FieldValues):
|
||||||
field = fields.BooleanField()
|
field = fields.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
|
class TestNullBooleanField(FieldValues):
|
||||||
|
"""
|
||||||
|
Valid and invalid values for `BooleanField`.
|
||||||
|
"""
|
||||||
|
valid_inputs = {
|
||||||
|
'true': True,
|
||||||
|
'false': False,
|
||||||
|
'null': None,
|
||||||
|
True: True,
|
||||||
|
False: False,
|
||||||
|
None: None
|
||||||
|
}
|
||||||
|
invalid_inputs = {
|
||||||
|
'foo': ['`foo` is not a valid boolean.'],
|
||||||
|
}
|
||||||
|
outputs = {
|
||||||
|
'true': True,
|
||||||
|
'false': False,
|
||||||
|
'null': None,
|
||||||
|
True: True,
|
||||||
|
False: False,
|
||||||
|
None: None
|
||||||
|
}
|
||||||
|
field = fields.NullBooleanField()
|
||||||
|
|
||||||
|
|
||||||
# String types...
|
# String types...
|
||||||
|
|
||||||
class TestCharField(FieldValues):
|
class TestCharField(FieldValues):
|
||||||
|
|
|
@ -90,7 +90,7 @@ class TestRegularFieldMappings(TestCase):
|
||||||
email_field = EmailField(max_length=100)
|
email_field = EmailField(max_length=100)
|
||||||
float_field = FloatField()
|
float_field = FloatField()
|
||||||
integer_field = IntegerField()
|
integer_field = IntegerField()
|
||||||
null_boolean_field = BooleanField(allow_null=True)
|
null_boolean_field = NullBooleanField()
|
||||||
positive_integer_field = IntegerField()
|
positive_integer_field = IntegerField()
|
||||||
positive_small_integer_field = IntegerField()
|
positive_small_integer_field = IntegerField()
|
||||||
slug_field = SlugField(max_length=100)
|
slug_field = SlugField(max_length=100)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user