[MERGE] fields.py: cleaned a bit fields.property.

bzr revid: vmt@openerp.com-20110712153056-r02ulhgq8gnorinr
This commit is contained in:
Vo Minh Thu 2011-07-12 17:30:56 +02:00
commit 622e58b183
2 changed files with 62 additions and 51 deletions

View File

@ -1212,34 +1212,30 @@ class serialized(_column):
self._symbol_get = self._deserialize_func
super(serialized, self).__init__(string=string, **args)
# TODO: review completly this class for speed improvement
class property(function):
def _get_default(self, obj, cr, uid, prop_name, context=None):
return self._get_defaults(obj, cr, uid, [prop_name], context=None)[0][prop_name]
return self._get_defaults(obj, cr, uid, [prop_name], context=None)[prop_name]
def _get_defaults(self, obj, cr, uid, prop_name, context=None):
def _get_defaults(self, obj, cr, uid, prop_names, context=None):
"""Get the default values for ``prop_names´´ property fields (result of ir.property.get() function for res_id = False).
:param list of string prop_names: list of name of property fields for those we want the default value
:return: map of property field names to their default value
:rtype: dict
"""
prop = obj.pool.get('ir.property')
domain = [('fields_id.model', '=', obj._name), ('fields_id.name','in',prop_name), ('res_id','=',False)]
ids = prop.search(cr, uid, domain, context=context)
replaces = {}
default_value = {}.fromkeys(prop_name, False)
for prop_rec in prop.browse(cr, uid, ids, context=context):
if default_value.get(prop_rec.fields_id.name, False):
continue
value = prop.get_by_record(cr, uid, prop_rec, context=context) or False
default_value[prop_rec.fields_id.name] = value
if value and (prop_rec.type == 'many2one'):
replaces.setdefault(value._name, {})
replaces[value._name][value.id] = True
return default_value, replaces
res = {}
for prop_name in prop_names:
res[prop_name] = prop.get(cr, uid, prop_name, obj._name, context=context)
return res
def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None):
prop = obj.pool.get('ir.property')
vids = [obj._name + ',' + str(oid) for oid in ids]
domain = [('fields_id.model', '=', obj._name), ('fields_id.name','in',prop_name)]
domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name)]
#domain = prop._get_domain(cr, uid, prop_name, obj._name, context)
if vids:
domain = [('res_id', 'in', vids)] + domain
@ -1274,48 +1270,48 @@ class property(function):
}, context=context)
return False
def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None):
prop = obj.pool.get('ir.property')
# get the default values (for res_id = False) for the property fields
default_val = self._get_defaults(obj, cr, uid, prop_names, context)
def _fnct_read(self, obj, cr, uid, ids, prop_name, obj_dest, context=None):
properties = obj.pool.get('ir.property')
domain = [('fields_id.model', '=', obj._name), ('fields_id.name','in',prop_name)]
domain += [('res_id','in', [obj._name + ',' + str(oid) for oid in ids])]
nids = properties.search(cr, uid, domain, context=context)
default_val,replaces = self._get_defaults(obj, cr, uid, prop_name, context)
# build the dictionary that will be returned
res = {}
for id in ids:
res[id] = default_val.copy()
brs = properties.browse(cr, uid, nids, context=context)
for prop in brs:
value = properties.get_by_record(cr, uid, prop, context=context)
res[prop.res_id.id][prop.fields_id.name] = value or False
if value and (prop.type == 'many2one'):
# check existence 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.
record_exists = obj.pool.get(value._name).exists(cr, 1, value.id)
if record_exists:
replaces.setdefault(value._name, {})
replaces[value._name][value.id] = True
else:
res[prop.res_id.id][prop.fields_id.name] = False
for rep in replaces:
# search+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.
nids = obj.pool.get(rep).search(cr, 1, [('id','in',replaces[rep].keys())], context=context)
replaces[rep] = dict(obj.pool.get(rep).name_get(cr, 1, nids, context=context))
for prop in prop_name:
for prop_name in prop_names:
property_field = obj._all_columns.get(prop_name).column
property_destination_obj = property_field._obj if property_field._type == 'many2one' else False
# If the property field is a m2o field, we will append the id of the value to name_get_ids
# in order to make a name_get in batch for all the ids needed.
name_get_ids = {}
for id in ids:
if res[id][prop] and hasattr(res[id][prop], '_name'):
res[id][prop] = (res[id][prop].id , replaces[res[id][prop]._name].get(res[id][prop].id, False))
# get the result of ir.property.get() for this res_id and save it in res if it's existing
obj_reference = obj._name + ',' + str(id)
value = prop.get(cr, uid, prop_name, obj._name, res_id=obj_reference, context=context)
if value:
res[id][prop_name] = value
# Check existence 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) in order to avoid
# pointing on an unexisting record.
if property_destination_obj:
if res[id][prop_name] and obj.pool.get(property_destination_obj).exists(cr, 1, res[id][prop_name].id):
name_get_ids[id] = res[id][prop_name].id
else:
res[id][prop_name] = False
if property_destination_obj:
# 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.)
name_get_values = dict(obj.pool.get(property_destination_obj).name_get(cr, 1, name_get_ids.values(), context=context))
# the property field is a m2o, we need to return a tuple with (id, name)
for k, v in name_get_ids.iteritems():
if res[k][prop_name]:
res[k][prop_name] = (v , name_get_values.get(v))
return res
def _field_get(self, cr, uid, model_name, prop):
if not self.field_id.get(cr.dbname):
cr.execute('SELECT id \

View File

@ -1387,6 +1387,21 @@ def upload_data(email, data, type='SURVEY'):
a.start()
return True
def get_and_group_by_field(cr, uid, obj, ids, field, context=None):
""" Read the values of ``field´´ for the given ``ids´´ and group ids by value.
:param string field: name of the field we want to read and group by
:return: mapping of field values to the list of ids that have it
:rtype: dict
"""
res = {}
for record in obj.read(cr, uid, ids, [field], context=context):
key = record[field]
res.setdefault(key[0] if isinstance(key, tuple) else key, []).append(record['id'])
return res
def get_and_group_by_company(cr, uid, obj, ids, context=None):
return get_and_group_by_field(cr, uid, obj, ids, field='company_id', context=context)
# port of python 2.6's attrgetter with support for dotted notation
def resolve_attr(obj, attr):