From 5cc863245ba873a2a7dcd8e16cece9581796d271 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 6 Nov 2014 09:59:41 +0100 Subject: [PATCH] [IMP] fields: improve _determine_default() and add test for inherited fields --- openerp/addons/test_inherit/models.py | 3 ++ .../addons/test_inherit/tests/test_inherit.py | 20 ++++++---- openerp/fields.py | 40 +++++++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/openerp/addons/test_inherit/models.py b/openerp/addons/test_inherit/models.py index 1a386a28274..422d59fd323 100644 --- a/openerp/addons/test_inherit/models.py +++ b/openerp/addons/test_inherit/models.py @@ -69,4 +69,7 @@ class daughter(models.Model): # simply redeclare the field without adding any option template_id = fields.Many2one() + # change the default value of an inherited field + name = fields.Char(default='Baz') + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/addons/test_inherit/tests/test_inherit.py b/openerp/addons/test_inherit/tests/test_inherit.py index e9be815d216..6909882b2c6 100644 --- a/openerp/addons/test_inherit/tests/test_inherit.py +++ b/openerp/addons/test_inherit/tests/test_inherit.py @@ -17,19 +17,25 @@ class test_inherits(common.TransactionCase): def test_field_extension(self): """ check the extension of a field in an inherited model """ - # the field mother.name should inherit required=True, and have "Bar" as - # a default value mother = self.env['test.inherit.mother'] + daughter = self.env['test.inherit.daughter'] + + # the field mother.name must have required=True and "Bar" as default field = mother._fields['name'] self.assertTrue(field.required) - self.assertEqual(field.default(mother), "Bar") - self.assertEqual(mother.default_get(['name']), {'name': "Bar"}) self.assertEqual(mother._defaults.get('name'), "Bar") + self.assertEqual(mother.default_get(['name']), {'name': "Bar"}) - # the field daughter.template_id should inherit - # model_name='test.inherit.mother', string='Template', required=True - daughter = self.env['test.inherit.daughter'] + # the field daughter.name must have required=False and "Baz" as default + field = daughter._fields['name'] + self.assertFalse(field.required) + self.assertEqual(field.default(mother), "Baz") + self.assertEqual(daughter._defaults.get('name'), "Baz") + self.assertEqual(daughter.default_get(['name']), {'name': "Baz"}) + + # the field daughter.template_id should have + # comodel_name='test.inherit.mother', string='Template', required=True field = daughter._fields['template_id'] self.assertEqual(field.comodel_name, 'test.inherit.mother') self.assertEqual(field.string, "Template") diff --git a/openerp/fields.py b/openerp/fields.py index 2d5e0c2d6a4..417591c3c53 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -347,30 +347,36 @@ class Field(object): # traverse the class hierarchy upwards, and take the first field # definition with a default or _defaults for self for klass in cls.__mro__: - field = klass.__dict__.get(name, self) - if not isinstance(field, type(self)): - return # klass contains another value overridden by self + if name in klass.__dict__: + field = klass.__dict__[name] + if not isinstance(field, type(self)): + # klass contains another value overridden by self + return - if 'default' in field._attrs: - # take the default in field, and adapt it for cls._defaults - value = field._attrs['default'] - if callable(value): - self.default = value - cls._defaults[name] = lambda model, cr, uid, context: \ - self.convert_to_write(value(model.browse(cr, uid, [], context))) - else: - self.default = lambda recs: value - cls._defaults[name] = value - return + if 'default' in field._attrs: + # take the default in field, and adapt it for cls._defaults + value = field._attrs['default'] + if callable(value): + from openerp import api + self.default = value + cls._defaults[name] = api.model( + lambda recs: self.convert_to_write(value(recs)) + ) + else: + self.default = lambda recs: value + cls._defaults[name] = value + return defaults = klass.__dict__.get('_defaults') or {} if name in defaults: # take the value from _defaults, and adapt it for self.default value = defaults[name] - value_func = value if callable(value) else lambda *args: value + if callable(value): + func = lambda recs: value(recs._model, recs._cr, recs._uid, recs._context) + else: + func = lambda recs: value self.default = lambda recs: self.convert_to_cache( - value_func(recs._model, recs._cr, recs._uid, recs._context), - recs, validate=False, + func(recs), recs, validate=False, ) cls._defaults[name] = value return