From 82f492bc2c5bbca8b02168075b5d5356f1b35951 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Fri, 9 Mar 2012 16:29:38 +0100 Subject: [PATCH] [FIX] related fields: fix and simplify search (was wrong with a single indirection) bzr revid: rco@openerp.com-20120309152938-n467ap8hnw406rau --- openerp/osv/fields.py | 18 +++-------- openerp/tests/__init__.py | 2 ++ openerp/tests/test_fields.py | 59 ++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 14 deletions(-) create mode 100644 openerp/tests/test_fields.py diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 7c1761a4aec..fdbd6a6f7cc 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1153,20 +1153,10 @@ class related(function): """ def _fnct_search(self, tobj, cr, uid, obj=None, name=None, domain=None, context=None): - self._field_get2(cr, uid, obj, context) - i = len(self._arg)-1 - sarg = name - while i>0: - if type(sarg) in [type([]), type( (1,) )]: - where = [(self._arg[i], 'in', sarg)] - else: - where = [(self._arg[i], '=', sarg)] - if domain: - where = map(lambda x: (self._arg[i],x[1], x[2]), domain) - domain = [] - sarg = obj.pool.get(self._relations[i]['object']).search(cr, uid, where, context=context) - i -= 1 - return [(self._arg[0], 'in', sarg)] + # assume self._arg = ('foo', 'bar', 'baz') + # domain = [(name, op, val)] => search [('foo.bar.baz', op, val)] + field = '.'.join(self._arg) + return map(lambda x: (field, x[1], x[2]), domain) def _fnct_write(self,obj,cr, uid, ids, field_name, values, args, context=None): self._field_get2(cr, uid, obj, context=context) diff --git a/openerp/tests/__init__.py b/openerp/tests/__init__.py index 5fccb07a082..e02a7d7042c 100644 --- a/openerp/tests/__init__.py +++ b/openerp/tests/__init__.py @@ -11,6 +11,7 @@ See the :ref:`test-framework` section in the :ref:`features` list. import test_expression import test_ir_sequence import test_orm +import test_fields fast_suite = [ test_ir_sequence, @@ -19,6 +20,7 @@ fast_suite = [ checks = [ test_expression, test_orm, + test_fields, ] # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tests/test_fields.py b/openerp/tests/test_fields.py new file mode 100644 index 00000000000..c049a43fc97 --- /dev/null +++ b/openerp/tests/test_fields.py @@ -0,0 +1,59 @@ +# +# test cases for fields access, etc. +# + +import unittest2 +import common + +import openerp +from openerp.osv import fields + +class TestRelatedField(common.TransactionCase): + + def setUp(self): + super(TestRelatedField, self).setUp() + self.partner = self.registry('res.partner') + + def do_test_company_field(self, field): + # get a partner with a non-null company_id + ids = self.partner.search(self.cr, self.uid, [('company_id', '!=', False)], limit=1) + partner = self.partner.browse(self.cr, self.uid, ids[0]) + + # check reading related field + self.assertEqual(partner[field], partner.company_id) + + # check that search on related field is equivalent to original field + ids1 = self.partner.search(self.cr, self.uid, [('company_id', '=', partner.company_id.id)]) + ids2 = self.partner.search(self.cr, self.uid, [(field, '=', partner.company_id.id)]) + self.assertEqual(ids1, ids2) + + def test_1_single_related(self): + """ test a related field with a single indirection like fields.related('foo') """ + # add a related field test_related_company_id on res.partner + old_columns = self.partner._columns + self.partner._columns = dict(old_columns) + self.partner._columns.update({ + 'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'), + }) + + self.do_test_company_field('single_related_company_id') + + # restore res.partner fields + self.partner._columns = old_columns + + def test_2_related_related(self): + """ test a related field referring to a related field """ + # add a related field on a related field on res.partner + old_columns = self.partner._columns + self.partner._columns = dict(old_columns) + self.partner._columns.update({ + 'single_related_company_id': fields.related('company_id', type='many2one', obj='res.company'), + 'related_related_company_id': fields.related('single_related_company_id', type='many2one', obj='res.company'), + }) + + self.do_test_company_field('related_related_company_id') + + # restore res.partner fields + self.partner._columns = old_columns + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: