Permit mixed casing of string values for BooleanField validation (#8970)

* be more permissive of mixed casing in validating strings for BooleanField values

* undo unnecessary change

* lint
This commit is contained in:
Nancy Eckenthal 2023-06-12 11:21:18 -04:00 committed by GitHub
parent 02d9bfc2dd
commit a180bde0fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 20 deletions

View File

@ -664,22 +664,27 @@ class BooleanField(Field):
default_empty_html = False default_empty_html = False
initial = False initial = False
TRUE_VALUES = { TRUE_VALUES = {
't', 'T', 't',
'y', 'Y', 'yes', 'Yes', 'YES', 'y',
'true', 'True', 'TRUE', 'yes',
'on', 'On', 'ON', 'true',
'1', 1, 'on',
True '1',
1,
True,
} }
FALSE_VALUES = { FALSE_VALUES = {
'f', 'F', 'f',
'n', 'N', 'no', 'No', 'NO', 'n',
'false', 'False', 'FALSE', 'no',
'off', 'Off', 'OFF', 'false',
'0', 0, 0.0, 'off',
False '0',
0,
0.0,
False,
} }
NULL_VALUES = {'null', 'Null', 'NULL', '', None} NULL_VALUES = {'null', '', None}
def __init__(self, **kwargs): def __init__(self, **kwargs):
if kwargs.get('allow_null', False): if kwargs.get('allow_null', False):
@ -687,22 +692,28 @@ class BooleanField(Field):
self.initial = None self.initial = None
super().__init__(**kwargs) super().__init__(**kwargs)
@staticmethod
def _lower_if_str(value):
if isinstance(value, str):
return value.lower()
return value
def to_internal_value(self, data): def to_internal_value(self, data):
with contextlib.suppress(TypeError): with contextlib.suppress(TypeError):
if data in self.TRUE_VALUES: if self._lower_if_str(data) in self.TRUE_VALUES:
return True return True
elif data in self.FALSE_VALUES: elif self._lower_if_str(data) in self.FALSE_VALUES:
return False return False
elif data in self.NULL_VALUES and self.allow_null: elif self._lower_if_str(data) in self.NULL_VALUES and self.allow_null:
return None return None
self.fail('invalid', input=data) self.fail("invalid", input=data)
def to_representation(self, value): def to_representation(self, value):
if value in self.TRUE_VALUES: if self._lower_if_str(value) in self.TRUE_VALUES:
return True return True
elif value in self.FALSE_VALUES: elif self._lower_if_str(value) in self.FALSE_VALUES:
return False return False
if value in self.NULL_VALUES and self.allow_null: if self._lower_if_str(value) in self.NULL_VALUES and self.allow_null:
return None return None
return bool(value) return bool(value)

View File

@ -695,8 +695,24 @@ class TestBooleanField(FieldValues):
Valid and invalid values for `BooleanField`. Valid and invalid values for `BooleanField`.
""" """
valid_inputs = { valid_inputs = {
'True': True,
'TRUE': True,
'tRuE': True,
't': True,
'T': True,
'true': True, 'true': True,
'on': True,
'ON': True,
'oN': True,
'False': False,
'FALSE': False,
'fALse': False,
'f': False,
'F': False,
'false': False, 'false': False,
'off': False,
'OFF': False,
'oFf': False,
'1': True, '1': True,
'0': False, '0': False,
1: True, 1: True,
@ -709,8 +725,24 @@ class TestBooleanField(FieldValues):
None: ['This field may not be null.'] None: ['This field may not be null.']
} }
outputs = { outputs = {
'True': True,
'TRUE': True,
'tRuE': True,
't': True,
'T': True,
'true': True, 'true': True,
'on': True,
'ON': True,
'oN': True,
'False': False,
'FALSE': False,
'fALse': False,
'f': False,
'F': False,
'false': False, 'false': False,
'off': False,
'OFF': False,
'oFf': False,
'1': True, '1': True,
'0': False, '0': False,
1: True, 1: True,