diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 50343b0d1fc..00e2681f324 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -164,6 +164,9 @@ class Message(models.Model): size = fields.Integer(compute='_compute_size', search='_search_size') double_size = fields.Integer(compute='_compute_double_size') discussion_name = fields.Char(related='discussion.name') + author_partner = fields.Many2one( + 'res.partner', compute='_compute_author_partner', + search='_search_author_partner') @api.one @api.constrains('author', 'discussion') @@ -209,6 +212,15 @@ class Message(models.Model): size = self.size self.double_size = self.double_size + size + @api.one + @api.depends('author', 'author.partner_id') + def _compute_author_partner(self): + self.author_partner = author.partner_id + + @api.model + def _search_author_partner(self, operator, value): + return [('author.partner_id', operator, value)] + class MixedModel(models.Model): _name = 'test_new_api.mixed' diff --git a/openerp/addons/test_new_api/tests/test_new_fields.py b/openerp/addons/test_new_api/tests/test_new_fields.py index c588ab59aca..59d85b211bf 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -424,6 +424,13 @@ class TestNewFields(common.TransactionCase): defaults = self.env['test_new_api.mixed'].default_get(['number']) self.assertEqual(defaults, {'number': 3.14}) + def test_50_search_many2one(self): + """ test search through a path of computed fields""" + messages = self.env['test_new_api.message'].search( + [('author_partner.name', '=', 'Demo User')]) + self.assertEqual(messages, self.env.ref('test_new_api.message_0_1')) + + class TestMagicFields(common.TransactionCase): diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index ef8a40dab90..b71db25eaa3 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -842,12 +842,12 @@ class expression(object): # as after transforming the column, it will go through this loop once again # ---------------------------------------- - elif len(path) > 1 and column._type == 'many2one' and column._auto_join: + elif len(path) > 1 and column and column._type == 'many2one' and column._auto_join: # res_partner.state_id = res_partner__state_id.id leaf.add_join_context(comodel, path[0], 'id', path[0]) push(create_substitution_leaf(leaf, (path[1], operator, right), comodel)) - elif len(path) > 1 and column._type == 'one2many' and column._auto_join: + elif len(path) > 1 and column and column._type == 'one2many' and column._auto_join: # res_partner.id = res_partner__bank_ids.partner_id leaf.add_join_context(comodel, 'id', column._fields_id, path[0]) domain = column._domain(model) if callable(column._domain) else column._domain @@ -858,16 +858,16 @@ class expression(object): push(create_substitution_leaf(leaf, elem, comodel)) push(create_substitution_leaf(leaf, AND_OPERATOR, comodel)) - elif len(path) > 1 and column._auto_join: + elif len(path) > 1 and column and column._auto_join: raise NotImplementedError('_auto_join attribute not supported on many2many column %s' % left) - elif len(path) > 1 and column._type == 'many2one': + elif len(path) > 1 and column and column._type == 'many2one': right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context) leaf.leaf = (path[0], 'in', right_ids) push(leaf) # Making search easier when there is a left operand as column.o2m or column.m2m - elif len(path) > 1 and column._type in ['many2many', 'one2many']: + elif len(path) > 1 and column and column._type in ['many2many', 'one2many']: right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context) table_ids = model.search(cr, uid, [(path[0], 'in', right_ids)], context=dict(context, active_test=False)) leaf.leaf = ('id', 'in', table_ids) @@ -884,7 +884,12 @@ class expression(object): domain = [] else: # Let the field generate a domain. - recs = model.browse(cr, uid, [], context) + if len(path) > 1: + right = comodel.search( + cr, uid, [(path[1], operator, right)], + context=context) + operator = 'in' + recs = model.browse(cr, uid, [], context=context) domain = field.determine_domain(recs, operator, right) if not domain: