formdata: return missing boolean value as False, not None (#50428)

This commit is contained in:
Frédéric Péters 2021-01-22 11:16:36 +01:00
parent 00ba2fb634
commit 7e4706e628
4 changed files with 39 additions and 6 deletions

View File

@ -591,8 +591,9 @@ def variable_test_data(pub):
formdef.name = 'foobarlazy'
formdef.fields = [
fields.StringField(id='0', label='string', varname='foo_foo'),
fields.BoolField(id='1', label='checkbox', varname='boolfield'),
fields.BoolField(id='2', label='checkbox', varname='boolfield2'),
fields.BoolField(id='1', label='checkbox', varname='boolfield', type='bool'),
fields.BoolField(id='2', label='checkbox', varname='boolfield2', type='bool'),
fields.BoolField(id='2b', label='checkbox', varname='boolfield3', type='bool'),
fields.DateField(id='3', label='date', varname='datefield'),
fields.ItemsField(id='4', label='items', items=['aa', 'ab', 'ac'], varname='itemsfield'),
fields.FileField(id='5', label='file', varname='filefield'),
@ -669,8 +670,11 @@ def test_lazy_formdata(pub, variable_test_data):
assert lazy_formdata.var.foo_foo == 'bar'
assert lazy_formdata.var.boolfield == 'False'
assert bool(lazy_formdata.var.boolfield) is False
assert lazy_formdata.var.boolfield.raw is False
assert lazy_formdata.var.boolfield2 == 'True'
assert lazy_formdata.var.boolfield2.raw is True
assert bool(lazy_formdata.var.boolfield2) is True
assert lazy_formdata.var.boolfield3.raw is False
assert lazy_formdata.var.datefield.raw == time.strptime('2018-07-31', '%Y-%m-%d')
assert lazy_formdata.var.datefield.tm_year == 2018
assert lazy_formdata.var.datefield.tm_mon == 7

View File

@ -2294,6 +2294,15 @@ def test_webservice_with_complex_data(http_requests, pub):
'bool': False,
}
# check an empty boolean field is sent as False
del formdata.data['6']
with get_publisher().complex_data():
item.perform(formdata)
assert http_requests.get_last('url') == 'http://remote.example.net'
assert http_requests.get_last('method') == 'POST'
payload = json.loads(http_requests.get_last('body'))
assert payload['bool'] is False
# check it's possible to disable complex data support
pub.load_site_options()
pub.site_options.set('options', 'complex-data', 'false')

View File

@ -216,6 +216,10 @@ def time(value, arg=None):
def parse_decimal(value, do_raise=False):
if hasattr(value, 'get_value'):
value = value.get_value() # unlazy
if isinstance(value, bool):
# treat all booleans as 0 (contrary to Python behaviour where
# decimal(True) == 1).
value = 0
if isinstance(value, six.string_types):
# replace , by . for French users comfort
value = value.replace(',', '.')

View File

@ -605,16 +605,22 @@ class LazyFormDataVar(object):
raise
maybe_varname = key.rsplit('_', 1)[0]
field = self.varnames[maybe_varname]
if key.endswith('_raw') and field.type == 'bool':
# turn None into False so boolean fields are always a boolean.
return bool(self._data.get(field.id))
if self._data.get(field.id) in (None, True, False):
# valid suffix and data of the correct type
return self._data.get(field.id)
raise KeyError(key)
if self._data.get(field.id) is None:
return None
# let boolean pass through, to get None handled as False
if field.type != 'bool':
if self._data.get(field.id) is None:
return None
if str(field.id) not in self._data:
raise KeyError(key)
if str(field.id) not in self._data:
raise KeyError(key)
klass = LazyFieldVar
if field.store_structured_value:
@ -625,6 +631,7 @@ class LazyFormDataVar(object):
'password': LazyFieldVarPassword,
'file': LazyFieldVarFile,
'block': LazyFieldVarBlock,
'bool': LazyFieldVarBool,
}.get(field.key, klass)
return klass(**self.get_field_kwargs(field))
@ -922,6 +929,15 @@ class LazyFieldVarMap(LazyFieldVarStructured):
return ['lat', 'lon']
class LazyFieldVarBool(LazyFieldVar):
def get_value(self):
return bool(self._data.get(self._field.id))
@property
def raw(self):
return self.get_value()
class LazyFieldVarPassword(LazyFieldVar):
def __getitem__(self, key):
# get subpart (cleartext, md5, sha1) if it exists