fields.related: simplify read and write methods

bzr revid: rco@openerp.com-20121029153504-157ss9948o86uv6z
This commit is contained in:
Raphael Collet 2012-10-29 16:35:04 +01:00
parent 42f0962f99
commit 7e7d877e17
2 changed files with 64 additions and 86 deletions

View File

@ -1158,80 +1158,44 @@ class related(function):
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)
if type(ids) != type([]):
ids=[ids]
objlst = obj.browse(cr, uid, ids)
for data in objlst:
t_id = data.id
t_data = data
for i in range(len(self.arg)):
if not t_data: break
field_detail = self._relations[i]
if not t_data[self.arg[i]]:
if self._type not in ('one2many', 'many2many'):
t_id = t_data['id']
t_data = False
elif field_detail['type'] in ('one2many', 'many2many'):
if self._type != "many2one":
t_id = t_data.id
t_data = t_data[self.arg[i]][0]
else:
t_data = False
else:
t_id = t_data['id']
t_data = t_data[self.arg[i]]
else:
model = obj.pool.get(self._relations[-1]['object'])
model.write(cr, uid, [t_id], {args[-1]: values}, context=context)
for record in obj.browse(cr, uid, ids, context=context):
# traverse all fields except the last one
for field in self.arg[:-1]:
record = record[field] or False
if not record:
break
elif isinstance(record, list):
# record is the result of a one2many or many2many field
record = record[0]
if record:
# write on the last field
record.write({self.arg[-1]: values})
def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None):
self._field_get2(cr, uid, obj, context)
if not ids: return {}
relation = obj._name
if self._type in ('one2many', 'many2many'):
res = dict([(i, []) for i in ids])
else:
res = {}.fromkeys(ids, False)
objlst = obj.browse(cr, SUPERUSER_ID, ids, context=context)
for data in objlst:
if not data:
continue
t_data = data
relation = obj._name
for i in range(len(self.arg)):
field_detail = self._relations[i]
relation = field_detail['object']
try:
if not t_data[self.arg[i]]:
t_data = False
break
except:
t_data = False
res = {}
for record in obj.browse(cr, SUPERUSER_ID, ids, context=context):
value = record
for field in self.arg:
if isinstance(value, list):
value = value[0]
value = value[field] or False
if not value:
break
if field_detail['type'] in ('one2many', 'many2many') and i != len(self.arg) - 1:
t_data = t_data[self.arg[i]][0]
elif t_data:
t_data = t_data[self.arg[i]]
if type(t_data) == type(objlst[0]):
res[data.id] = t_data.id
elif t_data:
res[data.id] = t_data
if self._type=='many2one':
ids = filter(None, res.values())
if ids:
# name_get as root, as seeing the name of a related
# object depends on access right of source document,
# not target, so user may not have access.
ng = dict(obj.pool.get(self._obj).name_get(cr, SUPERUSER_ID, ids, context=context))
for r in res:
if res[r]:
res[r] = (res[r], ng[res[r]])
res[record.id] = value
if self._type == 'many2one':
# res[id] is a browse_record or False; convert it to (id, name) or False
res = dict((id, value and value.id) for id, value in res.iteritems())
value_ids = filter(None, res.itervalues())
# name_get as root, as seeing the name of a related object depends on
# access right of source document, not target, so user may not have access.
value_name = dict(obj.pool.get(self._obj).name_get(cr, SUPERUSER_ID, value_ids, context=context))
res = dict((id, value_id and value_name[value_id]) for id, value_id in res.iteritems())
elif self._type in ('one2many', 'many2many'):
for r in res:
if res[r]:
res[r] = [x.id for x in res[r]]
# res[id] is a list of browse_record or False; convert it to a list of ids
res = dict((id, value and map(int, value) or []) for id, value in res.iteritems())
return res
def __init__(self, *arg, **args):
@ -1242,22 +1206,6 @@ class related(function):
# TODO: improve here to change self.store = {...} according to related objects
pass
def _field_get2(self, cr, uid, obj, context=None):
if self._relations:
return
result = []
obj_name = obj._name
for i in range(len(self._arg)):
f = obj.pool.get(obj_name).fields_get(cr, uid, [self._arg[i]], context=context)[self._arg[i]]
result.append({
'object': obj_name,
'type': f['type']
})
if f.get('relation',False):
obj_name = f['relation']
result[-1]['relation'] = f['relation']
self._relations = result
class sparse(function):

View File

@ -79,4 +79,34 @@ class TestRelatedField(common.TransactionCase):
# restore res.partner fields
self.partner._columns = old_columns
def test_3_read_write(self):
""" write on a related field """
# 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({
'related_company_partner_id': fields.related('company_id', 'partner_id', type='many2one', obj='res.partner'),
})
# find a company with a non-null partner_id
company_ids = self.company.search(self.cr, self.uid, [('partner_id', '!=', False)], limit=1)
company = self.company.browse(self.cr, self.uid, company_ids[0])
# find partners that satisfy [('partner_id.company_id', '=', company.id)]
partner_ids = self.partner.search(self.cr, self.uid, [('related_company_partner_id', '=', company.id)])
partner = self.partner.browse(self.cr, self.uid, partner_ids[0])
# create a new partner, and assign it to company
new_partner_id = self.partner.create(self.cr, self.uid, {'name': 'Foo'})
partner.write({'related_company_partner_id': new_partner_id})
company = self.company.browse(self.cr, self.uid, company_ids[0])
self.assertEqual(company.partner_id.id, new_partner_id)
partner = self.partner.browse(self.cr, self.uid, partner_ids[0])
self.assertEqual(partner.related_company_partner_id.id, new_partner_id)
# restore res.partner fields
self.partner._columns = old_columns
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: