diff --git a/CHANGELOG b/CHANGELOG index 1ae6e48f25..6d4dda26d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add translated descriptor for Selection field * Add tree_state attribute on tree view * Allow to sync XML data * Remove on_change calls in Model.default_get diff --git a/doc/ref/models/fields.rst b/doc/ref/models/fields.rst index 85fd0ca809..91973464e3 100644 --- a/doc/ref/models/fields.rst +++ b/doc/ref/models/fields.rst @@ -413,6 +413,13 @@ A string field with limited values to choice. If true, the human-readable values will be translated. Default value is ``True``. +Instance methods: + +.. method:: Selection.translated([name]) + + Returns a descriptor for the translated value of the field. The descriptor + must be used on the same class as the field. + Reference --------- diff --git a/doc/ref/models/models.rst b/doc/ref/models/models.rst index f5d50e5899..110636e99d 100644 --- a/doc/ref/models/models.rst +++ b/doc/ref/models/models.rst @@ -309,6 +309,8 @@ CLass methods: Return a list of list of values for each ``records``. The list of values follows ``fields_names``. Relational fields are defined with ``/`` at any depth. + Descriptor on fields are available by appending ``.`` and the name of the + method on the field that returns the descriptor. .. classmethod:: ModelStorage.import_data(fields_names, data) diff --git a/trytond/model/fields/selection.py b/trytond/model/fields/selection.py index 230e153058..98fcb84542 100644 --- a/trytond/model/fields/selection.py +++ b/trytond/model/fields/selection.py @@ -63,3 +63,29 @@ class Selection(Field): for key, value in selections: whens.append((column == key, value)) return [Case(*whens, else_=column)] + + def translated(self, name=None): + "Return a descriptor for the translated value of the field" + if name is None: + name = self.name + if name is None: + raise ValueError('Missing name argument') + return TranslatedSelection(name) + + +class TranslatedSelection(object): + 'A descriptor for translated value of Selection field' + + def __init__(self, name): + self.name = name + + def __get__(self, inst, cls): + if inst is None: + return self + selection = dict(cls.fields_get([self.name])[self.name]['selection']) + value = getattr(inst, self.name) + # None and '' are equivalent + if value is None or value == '': + if value not in selection: + value = {None: '', '': None}[value] + return selection[value] diff --git a/trytond/model/modelstorage.py b/trytond/model/modelstorage.py index 6afed60aed..57dbbd3e18 100644 --- a/trytond/model/modelstorage.py +++ b/trytond/model/modelstorage.py @@ -452,6 +452,9 @@ class ModelStorage(Model): if not isinstance(value, ModelStorage): break field_name = fields_tree[i] + descriptor = None + if '.' in field_name: + field_name, descriptor = field_name.split('.') eModel = pool.get(value.__name__) field = eModel._fields[field_name] if field.states and 'invisible' in field.states: @@ -467,7 +470,10 @@ class ModelStorage(Model): if invisible: value = '' break - value = getattr(value, field_name) + if descriptor: + value = getattr(field, descriptor)().__get__(value, eModel) + else: + value = getattr(value, field_name) if isinstance(value, (list, tuple)): first = True child_fields_names = [(x[:i + 1] == fields_tree[:i + 1] and diff --git a/trytond/tests/test.py b/trytond/tests/test.py index f6cbaf7530..5f812f24c7 100644 --- a/trytond/tests/test.py +++ b/trytond/tests/test.py @@ -604,6 +604,7 @@ class Selection(ModelSQL): select = fields.Selection([ ('', ''), ('arabic', 'Arabic'), ('hexa', 'Hexadecimal')], 'Selection') + select_string = select.translated('select') dyn_select = fields.Selection('get_selection', 'Instance Dynamic Selection') dyn_select_static = fields.Selection('static_selection', diff --git a/trytond/tests/test_exportdata.py b/trytond/tests/test_exportdata.py index 989d2d2867..417b52b000 100644 --- a/trytond/tests/test_exportdata.py +++ b/trytond/tests/test_exportdata.py @@ -216,8 +216,9 @@ class ExportDataTestCase(unittest.TestCase): 'selection': 'select1', }]) self.assertEqual( - self.export_data.export_data([export1], ['selection']), - [['select1']]) + self.export_data.export_data([export1], ['selection', + 'selection.translated']), + [['select1', 'Select 1']]) export2, = self.export_data.create([{ 'selection': None, diff --git a/trytond/tests/test_fields.py b/trytond/tests/test_fields.py index fa874aea3e..2c436f6e2e 100644 --- a/trytond/tests/test_fields.py +++ b/trytond/tests/test_fields.py @@ -3060,10 +3060,12 @@ class FieldsTestCase(unittest.TestCase): selection1, = self.selection.create([{'select': 'arabic'}]) self.assert_(selection1) self.assertEqual(selection1.select, 'arabic') + self.assertEqual(selection1.select_string, 'Arabic') selection2, = self.selection.create([{'select': None}]) self.assert_(selection2) self.assertEqual(selection2.select, None) + self.assertEqual(selection2.select_string, '') self.assertRaises(UserError, self.selection.create, [{'select': 'chinese'}])