fields.related: simplify read and write methods
bzr revid: rco@openerp.com-20121029153504-157ss9948o86uv6z
This commit is contained in:
parent
42f0962f99
commit
7e7d877e17
|
@ -1158,80 +1158,44 @@ class related(function):
|
||||||
return map(lambda x: (field, x[1], x[2]), domain)
|
return map(lambda x: (field, x[1], x[2]), domain)
|
||||||
|
|
||||||
def _fnct_write(self,obj,cr, uid, ids, field_name, values, args, context=None):
|
def _fnct_write(self,obj,cr, uid, ids, field_name, values, args, context=None):
|
||||||
self._field_get2(cr, uid, obj, context=context)
|
for record in obj.browse(cr, uid, ids, context=context):
|
||||||
if type(ids) != type([]):
|
# traverse all fields except the last one
|
||||||
ids=[ids]
|
for field in self.arg[:-1]:
|
||||||
objlst = obj.browse(cr, uid, ids)
|
record = record[field] or False
|
||||||
for data in objlst:
|
if not record:
|
||||||
t_id = data.id
|
break
|
||||||
t_data = data
|
elif isinstance(record, list):
|
||||||
for i in range(len(self.arg)):
|
# record is the result of a one2many or many2many field
|
||||||
if not t_data: break
|
record = record[0]
|
||||||
field_detail = self._relations[i]
|
if record:
|
||||||
if not t_data[self.arg[i]]:
|
# write on the last field
|
||||||
if self._type not in ('one2many', 'many2many'):
|
record.write({self.arg[-1]: values})
|
||||||
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)
|
|
||||||
|
|
||||||
def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None):
|
def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None):
|
||||||
self._field_get2(cr, uid, obj, context)
|
res = {}
|
||||||
if not ids: return {}
|
for record in obj.browse(cr, SUPERUSER_ID, ids, context=context):
|
||||||
relation = obj._name
|
value = record
|
||||||
if self._type in ('one2many', 'many2many'):
|
for field in self.arg:
|
||||||
res = dict([(i, []) for i in ids])
|
if isinstance(value, list):
|
||||||
else:
|
value = value[0]
|
||||||
res = {}.fromkeys(ids, False)
|
value = value[field] or False
|
||||||
|
if not value:
|
||||||
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
|
|
||||||
break
|
break
|
||||||
if field_detail['type'] in ('one2many', 'many2many') and i != len(self.arg) - 1:
|
res[record.id] = value
|
||||||
t_data = t_data[self.arg[i]][0]
|
|
||||||
elif t_data:
|
if self._type == 'many2one':
|
||||||
t_data = t_data[self.arg[i]]
|
# res[id] is a browse_record or False; convert it to (id, name) or False
|
||||||
if type(t_data) == type(objlst[0]):
|
res = dict((id, value and value.id) for id, value in res.iteritems())
|
||||||
res[data.id] = t_data.id
|
value_ids = filter(None, res.itervalues())
|
||||||
elif t_data:
|
# name_get as root, as seeing the name of a related object depends on
|
||||||
res[data.id] = t_data
|
# access right of source document, not target, so user may not have access.
|
||||||
if self._type=='many2one':
|
value_name = dict(obj.pool.get(self._obj).name_get(cr, SUPERUSER_ID, value_ids, context=context))
|
||||||
ids = filter(None, res.values())
|
res = dict((id, value_id and value_name[value_id]) for id, value_id in res.iteritems())
|
||||||
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]])
|
|
||||||
elif self._type in ('one2many', 'many2many'):
|
elif self._type in ('one2many', 'many2many'):
|
||||||
for r in res:
|
# res[id] is a list of browse_record or False; convert it to a list of ids
|
||||||
if res[r]:
|
res = dict((id, value and map(int, value) or []) for id, value in res.iteritems())
|
||||||
res[r] = [x.id for x in res[r]]
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def __init__(self, *arg, **args):
|
def __init__(self, *arg, **args):
|
||||||
|
@ -1242,22 +1206,6 @@ class related(function):
|
||||||
# TODO: improve here to change self.store = {...} according to related objects
|
# TODO: improve here to change self.store = {...} according to related objects
|
||||||
pass
|
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):
|
class sparse(function):
|
||||||
|
|
||||||
|
|
|
@ -79,4 +79,34 @@ class TestRelatedField(common.TransactionCase):
|
||||||
# restore res.partner fields
|
# restore res.partner fields
|
||||||
self.partner._columns = old_columns
|
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:
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
Loading…
Reference in New Issue