NullBooleanField

This commit is contained in:
Tom Christie 2014-09-23 14:30:17 +01:00
parent f22d0afc3d
commit 0404f09a7e
5 changed files with 67 additions and 5 deletions

View File

@ -289,6 +289,10 @@ class BooleanField(Field):
TRUE_VALUES = set(('t', 'T', 'true', 'True', 'TRUE', '1', 1, True))
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):
if data in self.TRUE_VALUES:
return True
@ -297,7 +301,38 @@ class BooleanField(Field):
self.fail('invalid', input=data)
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
if value in self.TRUE_VALUES:
return True

View File

@ -333,7 +333,7 @@ class ModelSerializer(Serializer):
models.FloatField: FloatField,
models.ImageField: ImageField,
models.IntegerField: IntegerField,
models.NullBooleanField: BooleanField,
models.NullBooleanField: NullBooleanField,
models.PositiveIntegerField: IntegerField,
models.PositiveSmallIntegerField: IntegerField,
models.SlugField: SlugField,

View File

@ -74,7 +74,7 @@ def get_field_kwargs(field_name, model_field):
kwargs['choices'] = model_field.flatchoices
return kwargs
if model_field.null:
if model_field.null and not isinstance(model_field, models.NullBooleanField):
kwargs['allow_null'] = True
if model_field.blank:

View File

@ -124,7 +124,8 @@ class TestBooleanField(FieldValues):
False: False,
}
invalid_inputs = {
'foo': ['`foo` is not a valid boolean.']
'foo': ['`foo` is not a valid boolean.'],
None: ['This field may not be null.']
}
outputs = {
'true': True,
@ -140,6 +141,32 @@ class TestBooleanField(FieldValues):
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...
class TestCharField(FieldValues):

View File

@ -90,7 +90,7 @@ class TestRegularFieldMappings(TestCase):
email_field = EmailField(max_length=100)
float_field = FloatField()
integer_field = IntegerField()
null_boolean_field = BooleanField(allow_null=True)
null_boolean_field = NullBooleanField()
positive_integer_field = IntegerField()
positive_small_integer_field = IntegerField()
slug_field = SlugField(max_length=100)