[FIX] openerp: export empty string instead of None

xmlrpc 1.0 does not support None/null, so commit f3e4d0a will break xmlrpc api.
Therefore, we export an empty string if the field is empty, instead of False or
None. For integers and floats, zero is exported.

opw-643966
This commit is contained in:
Nicolas Martinelli 2015-07-10 10:23:41 +02:00
parent b4f7288193
commit 282fc4a850
2 changed files with 34 additions and 29 deletions

View File

@ -49,7 +49,7 @@ class test_integer_field(CreatorCase):
def test_0(self): def test_0(self):
self.assertEqual( self.assertEqual(
self.export(0), self.export(0),
[[False]]) [[u'0']])
def test_basic_value(self): def test_basic_value(self):
self.assertEqual( self.assertEqual(
@ -72,7 +72,7 @@ class test_float_field(CreatorCase):
def test_0(self): def test_0(self):
self.assertEqual( self.assertEqual(
self.export(0.0), self.export(0.0),
[[False]]) [[u'0.0']])
def test_epsilon(self): def test_epsilon(self):
self.assertEqual( self.assertEqual(
@ -100,14 +100,14 @@ class test_decimal_field(CreatorCase):
def test_0(self): def test_0(self):
self.assertEqual( self.assertEqual(
self.export(0.0), self.export(0.0),
[[False]]) [[u'0.0']])
def test_epsilon(self): def test_epsilon(self):
""" epsilon gets sliced to 0 due to precision """ epsilon gets sliced to 0 due to precision
""" """
self.assertEqual( self.assertEqual(
self.export(0.000000000027), self.export(0.000000000027),
[[False]]) [[u'0.0']])
def test_negative(self): def test_negative(self):
self.assertEqual( self.assertEqual(
@ -129,7 +129,7 @@ class test_string_field(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(""), self.export(""),
[[False]]) [['']])
def test_within_bounds(self): def test_within_bounds(self):
self.assertEqual( self.assertEqual(
self.export("foobar"), self.export("foobar"),
@ -148,7 +148,7 @@ class test_unbound_string_field(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(""), self.export(""),
[[False]]) [['']])
def test_small(self): def test_small(self):
self.assertEqual( self.assertEqual(
self.export("foobar"), self.export("foobar"),
@ -170,7 +170,7 @@ class test_text(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(""), self.export(""),
[[False]]) [['']])
def test_small(self): def test_small(self):
self.assertEqual( self.assertEqual(
self.export("foobar"), self.export("foobar"),
@ -190,7 +190,7 @@ class test_date(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(False), self.export(False),
[[False]]) [['']])
def test_basic(self): def test_basic(self):
self.assertEqual( self.assertEqual(
self.export('2011-11-07'), self.export('2011-11-07'),
@ -202,7 +202,7 @@ class test_datetime(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(False), self.export(False),
[[False]]) [['']])
def test_basic(self): def test_basic(self):
self.assertEqual( self.assertEqual(
self.export('2011-11-07 21:05:48'), self.export('2011-11-07 21:05:48'),
@ -265,7 +265,7 @@ class test_selection_function(CreatorCase):
def test_empty(self): def test_empty(self):
self.assertEqual( self.assertEqual(
self.export(False), self.export(False),
[[None]]) [['']])
def test_value(self): def test_value(self):
# FIXME: selection functions export the *value* itself # FIXME: selection functions export the *value* itself
@ -278,7 +278,7 @@ class test_selection_function(CreatorCase):
# fucking hell # fucking hell
self.assertEqual( self.assertEqual(
self.export(0), self.export(0),
[[None]]) [['']])
class test_m2o(CreatorCase): class test_m2o(CreatorCase):
model_name = 'export.many2one' model_name = 'export.many2one'

View File

@ -781,9 +781,9 @@ class Field(object):
""" convert ``value`` from the cache to a valid value for export. The """ convert ``value`` from the cache to a valid value for export. The
parameter ``env`` is given for managing translations. parameter ``env`` is given for managing translations.
""" """
if env.context.get('export_raw_data'): if not value:
return value return ''
return bool(value) and ustr(value) return value if env.context.get('export_raw_data') else ustr(value)
def convert_to_display_name(self, value, record=None): def convert_to_display_name(self, value, record=None):
""" convert ``value`` from the cache to a suitable display name. """ """ convert ``value`` from the cache to a suitable display name. """
@ -1035,6 +1035,11 @@ class Integer(Field):
# special case, when an integer field is used as inverse for a one2many # special case, when an integer field is used as inverse for a one2many
records._cache[self] = value.id or 0 records._cache[self] = value.id or 0
def convert_to_export(self, value, env):
if value or value == 0:
return value if env.context.get('export_raw_data') else ustr(value)
return ''
class Float(Field): class Float(Field):
""" The precision digits are given by the attribute """ The precision digits are given by the attribute
@ -1082,6 +1087,11 @@ class Float(Field):
digits = self.digits digits = self.digits
return float_round(value, precision_digits=digits[1]) if digits else value return float_round(value, precision_digits=digits[1]) if digits else value
def convert_to_export(self, value, env):
if value or value == 0.0:
return value if env.context.get('export_raw_data') else ustr(value)
return ''
class _String(Field): class _String(Field):
""" Abstract class for string fields. """ """ Abstract class for string fields. """
@ -1093,11 +1103,6 @@ class _String(Field):
_related_translate = property(attrgetter('translate')) _related_translate = property(attrgetter('translate'))
_description_translate = property(attrgetter('translate')) _description_translate = property(attrgetter('translate'))
def convert_to_export(self, value, env):
if env.context.get('export_raw_data'):
return value if value else None
return bool(value) and ustr(value)
class Char(_String): class Char(_String):
""" Basic string field, can be length-limited, usually displayed as a """ Basic string field, can be length-limited, usually displayed as a
@ -1216,9 +1221,9 @@ class Date(Field):
return self.to_string(value) return self.to_string(value)
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
if value and env.context.get('export_raw_data'): if not value:
return self.from_string(value) or None return ''
return bool(value) and ustr(value) return self.from_string(value) if env.context.get('export_raw_data') else ustr(value)
class Datetime(Field): class Datetime(Field):
@ -1285,9 +1290,9 @@ class Datetime(Field):
return self.to_string(value) return self.to_string(value)
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
if value and env.context.get('export_raw_data'): if not value:
return self.from_string(value) or None return ''
return bool(value) and ustr(value) return self.from_string(value) if env.context.get('export_raw_data') else ustr(value)
def convert_to_display_name(self, value, record=None): def convert_to_display_name(self, value, record=None):
assert record, 'Record expected' assert record, 'Record expected'
@ -1395,7 +1400,7 @@ class Selection(Field):
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
if not isinstance(self.selection, list): if not isinstance(self.selection, list):
# FIXME: this reproduces an existing buggy behavior! # FIXME: this reproduces an existing buggy behavior!
return value or None return value if value else ''
for item in self._description_selection(env): for item in self._description_selection(env):
if item[0] == value: if item[0] == value:
return item[1] return item[1]
@ -1432,7 +1437,7 @@ class Reference(Selection):
return "%s,%s" % (value._name, value.id) if value else False return "%s,%s" % (value._name, value.id) if value else False
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
return value.name_get()[0][1] if value else None return value.name_get()[0][1] if value else ''
def convert_to_display_name(self, value, record=None): def convert_to_display_name(self, value, record=None):
return ustr(value and value.display_name) return ustr(value and value.display_name)
@ -1572,7 +1577,7 @@ class Many2one(_Relational):
return value.id return value.id
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
return value.name_get()[0][1] if value else None return value.name_get()[0][1] if value else ''
def convert_to_display_name(self, value, record=None): def convert_to_display_name(self, value, record=None):
return ustr(value.display_name) return ustr(value.display_name)
@ -1678,7 +1683,7 @@ class _RelationalMulti(_Relational):
return result return result
def convert_to_export(self, value, env): def convert_to_export(self, value, env):
return ','.join(name for id, name in value.name_get()) if value else None return ','.join(name for id, name in value.name_get()) if value else ''
def convert_to_display_name(self, value, record=None): def convert_to_display_name(self, value, record=None):
raise NotImplementedError() raise NotImplementedError()