From 242a9e9b05c682c24f8e06c458900731fab84e1f Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 7 Jul 2011 15:26:14 +0200 Subject: [PATCH 01/10] [IMP] tools: added a function to get and sort by field bzr revid: qdp-launchpad@openerp.com-20110707132614-c6letgrkz4d6vm0i --- openerp/tools/misc.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index dc66142fc4a..96e85413bff 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -1387,6 +1387,22 @@ def upload_data(email, data, type='SURVEY'): a.start() return True +def get_and_sort_by_field(cr, uid, obj, ids, field, context=None): + """ + This function reads a field on several ids and build a dictionary {KEY:VALUE} with: + KEY: field value + VALUE: all the ids of obj that share the same value for that field + """ + value_fields = obj.read(cr, uid, ids, [field],context=context) + res = {} + for item in value_fields: + key = item[field] + if isinstance(key,tuple): + key = key[0] + if not key in set_field: + res[key] = [] + res[key].append(item['id']) + return res # port of python 2.6's attrgetter with support for dotted notation def resolve_attr(obj, attr): From 1e57f21cb772a8f9f54a26d9d101d9ba0ef3121a Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 7 Jul 2011 15:37:33 +0200 Subject: [PATCH 02/10] [IMP] openerp/osv/fields.py: reading a property field is now using the function get() of ir.property object. bzr revid: qdp-launchpad@openerp.com-20110707133733-aua4dygdjjmhryap --- openerp/osv/fields.py | 80 ++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index a9fd20e2a65..901f4951cef 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1212,6 +1212,7 @@ class serialized(_column): self._symbol_get = self._deserialize_func super(serialized, self).__init__(string=string, **args) +import orm # TODO: review completly this class for speed improvement class property(function): @@ -1219,21 +1220,21 @@ 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] - def _get_defaults(self, obj, cr, uid, prop_name, context=None): + def _get_defaults(self, obj, cr, uid, prop_names, context=None): + """ + This function receives a list of property field name and returns a dictionary with + KEY: name of property fields + VALUE: the result of ir.property.get() function for res_id = False + """ 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 + default_value = {}.fromkeys(prop_names, False) + for prop_name in prop_names: + for value in [prop.get(cr, uid, prop_name, obj._name, context=context)]: + if isinstance(value, orm.browse_null): + continue + default_value[prop_name] = value + return default_value def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None): prop = obj.pool.get('ir.property') @@ -1274,48 +1275,35 @@ class property(function): }, context=context) return False - - def _fnct_read(self, obj, cr, uid, ids, prop_name, obj_dest, context=None): + def _fnct_read(self, obj, cr, uid, ids, prop_names, 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) + #get the default values (for res_id = False) for the property fields + default_val = self._get_defaults(obj, cr, uid, prop_names, 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 in prop_names: + #if the property field is a m2o field, we will append the id of the value to name_get_list_ids + #in order to make a name_get in batch for all the ids needed. + name_get_list_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 + value = properties.get(cr, uid, prop, obj._name, res_id=id, context=context) + if value: + res[id][prop] = value + if isinstance(default_val[prop], orm.browse_record): + name_get_list_ids.append(res[id][prop].id) + if isinstance(default_val[prop], orm.browse_record): + name_get_values = dict(obj.pool.get(default_val[prop]._name).name_get(cr, uid, name_get_list_ids, context=context)) + #if the property field is a m2o, we need to return a tuple with (id, name) + for id in ids: + if res[id][prop] and isinstance(res[id][prop], orm.browse_record): + res[id][prop] = (res[id][prop].id , name_get_values.get(res[id][prop].id, False)) return res - def _field_get(self, cr, uid, model_name, prop): if not self.field_id.get(cr.dbname): cr.execute('SELECT id \ From 760471863a485e49c4d40b694c95e4323de464ed Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Thu, 7 Jul 2011 16:03:59 +0200 Subject: [PATCH 03/10] [FIX] fields.py: reading and writing on ir.property fields bzr revid: qdp-launchpad@openerp.com-20110707140359-mxj1or10gzvde3te --- openerp/osv/fields.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 901f4951cef..93ad0169cf0 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1218,7 +1218,7 @@ import orm 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_names, context=None): """ @@ -1291,7 +1291,8 @@ class property(function): name_get_list_ids = [] for id in ids: #get the result of ir.property.get() for this res_id and save it in res if it's existing - value = properties.get(cr, uid, prop, obj._name, res_id=id, context=context) + obj_reference = obj._name + ',' + str(id) + value = properties.get(cr, uid, prop, obj._name, res_id=obj_reference, context=context) if value: res[id][prop] = value if isinstance(default_val[prop], orm.browse_record): From b363bfb39235c084a28c4416e65278108af8448b Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Fri, 8 Jul 2011 14:51:06 +0200 Subject: [PATCH 04/10] [FIX] openerp/osv/fields.py: _get_defaults() and _fnct_read() of property fields cleaned and fixed as requested on merge proposal -_get_defaults(): improved docstring in order to follow RST docstring format -_get_defaults(): removed weird loop in _get_defaults as there is always 1 element only -_fnct_read(): make name_get as root -_fnct_read(): check existence for m2o fields (as root) -_fnct_read(): check for type of property field is now done on reliable information bzr revid: qdp-launchpad@openerp.com-20110708125106-0q0wj5zncaa7yp0w --- openerp/osv/fields.py | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 93ad0169cf0..1892e8a2b99 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1221,19 +1221,20 @@ class property(function): return self._get_defaults(obj, cr, uid, [prop_name], context=None)[prop_name] def _get_defaults(self, obj, cr, uid, prop_names, context=None): - """ - This function receives a list of property field name and returns a dictionary with - KEY: name of property fields - VALUE: the result of ir.property.get() function for res_id = False + """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') replaces = {} default_value = {}.fromkeys(prop_names, False) for prop_name in prop_names: - for value in [prop.get(cr, uid, prop_name, obj._name, context=context)]: - if isinstance(value, orm.browse_null): - continue - default_value[prop_name] = value + value = prop.get(cr, uid, prop_name, obj._name, context=context) + if isinstance(value, orm.browse_null): + continue + default_value[prop_name] = value return default_value def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None): @@ -1286,6 +1287,11 @@ class property(function): res[id] = default_val.copy() for prop in prop_names: + # get the type of property field as root (as access depends on access right of source document, + # not ir.property object, so user may not have acces) + property_field_id = properties.search(cr, 1, [('name','=',prop)], context=context) + property_field_type = property_field_id and properties.read(cr, 1, property_field_id, ['type'], context=context)[0]['type'] or False + property_destination_obj = None #if the property field is a m2o field, we will append the id of the value to name_get_list_ids #in order to make a name_get in batch for all the ids needed. name_get_list_ids = [] @@ -1295,10 +1301,21 @@ class property(function): value = properties.get(cr, uid, prop, obj._name, res_id=obj_reference, context=context) if value: res[id][prop] = value - if isinstance(default_val[prop], orm.browse_record): - name_get_list_ids.append(res[id][prop].id) - if isinstance(default_val[prop], orm.browse_record): - name_get_values = dict(obj.pool.get(default_val[prop]._name).name_get(cr, uid, name_get_list_ids, context=context)) + # 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 res[id][prop] and property_field_type == 'many2one': + if not property_destination_obj: + property_destination_obj = res[id][prop]._name + if not obj.pool.get(res[id][prop]._name).exists(cr, 1, res[id][prop].id): + res[id][prop] = False + if property_destination_obj and property_field_type == 'many2one': + # 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_list_ids = [res[id][prop].id for id in ids if res[id][prop]] + name_get_values = dict(obj.pool.get(property_destination_obj).name_get(cr, 1, name_get_list_ids, context=context)) #if the property field is a m2o, we need to return a tuple with (id, name) for id in ids: if res[id][prop] and isinstance(res[id][prop], orm.browse_record): From dae911decc548502a85186c7c8ef873167e8145e Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Fri, 8 Jul 2011 15:25:37 +0200 Subject: [PATCH 05/10] [FIX] tools: get_and_sort_by_field function fixed and cleaned as asked in merge proposal - fixed error of undefined variable set_field - improved docstring to follow standard RST formatting - renamed function into get_and_group_by_field to depict more precisely what it's doing - created a specific function get_and_group_by_company to hide the complexity bzr revid: qdp-launchpad@openerp.com-20110708132537-d7c4trk0nl5ngny0 --- openerp/tools/misc.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 96e85413bff..4c730c91c58 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -1387,11 +1387,12 @@ def upload_data(email, data, type='SURVEY'): a.start() return True -def get_and_sort_by_field(cr, uid, obj, ids, field, context=None): - """ - This function reads a field on several ids and build a dictionary {KEY:VALUE} with: - KEY: field value - VALUE: all the ids of obj that share the same value for that field +def get_and_group_by_field(cr, uid, obj, ids, field, context=None): + """Reads ``field´´ on given ``ids´´ and map all the ones that shares the same 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 """ value_fields = obj.read(cr, uid, ids, [field],context=context) res = {} @@ -1399,11 +1400,14 @@ def get_and_sort_by_field(cr, uid, obj, ids, field, context=None): key = item[field] if isinstance(key,tuple): key = key[0] - if not key in set_field: + if not key in res: res[key] = [] res[key].append(item['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): for name in attr.split("."): From 2fe91df6add612fadb3452f553f312302dd8d954 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 11 Jul 2011 14:34:14 +0200 Subject: [PATCH 06/10] [IMP] fields.py: tidying up before merging in trunk. bzr revid: vmt@openerp.com-20110711123414-5nf29awpui5x0pp6 --- openerp/osv/fields.py | 56 +++++++++++++++++++------------------------ openerp/tools/misc.py | 13 ++++------ 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 1892e8a2b99..e16836e1163 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1228,20 +1228,16 @@ class property(function): :rtype: dict """ prop = obj.pool.get('ir.property') - replaces = {} default_value = {}.fromkeys(prop_names, False) for prop_name in prop_names: - value = prop.get(cr, uid, prop_name, obj._name, context=context) - if isinstance(value, orm.browse_null): - continue - default_value[prop_name] = value + default_value[prop_name] = prop.get(cr, uid, prop_name, obj._name, context=context) return default_value 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 @@ -1277,49 +1273,45 @@ class property(function): return False def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None): - properties = obj.pool.get('ir.property') - #get the default values (for res_id = False) for the property fields + 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) - #build the dictionary that will be returned + # build the dictionary that will be returned res = {} for id in ids: res[id] = default_val.copy() - for prop in prop_names: - # get the type of property field as root (as access depends on access right of source document, - # not ir.property object, so user may not have acces) - property_field_id = properties.search(cr, 1, [('name','=',prop)], context=context) - property_field_type = property_field_id and properties.read(cr, 1, property_field_id, ['type'], context=context)[0]['type'] or False - property_destination_obj = None - #if the property field is a m2o field, we will append the id of the value to name_get_list_ids - #in order to make a name_get in batch for all the ids needed. + for prop_name in prop_names: + property_field = obj._all_columns.get(prop_name).column + property_field_type = property_field.type + property_destination_obj = property_field.relation # false if type is not a many2one + # If the property field is a m2o field, we will append the id of the value to name_get_list_ids + # in order to make a name_get in batch for all the ids needed. name_get_list_ids = [] for id in ids: - #get the result of ir.property.get() for this res_id and save it in res if it's existing + # 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 = properties.get(cr, uid, prop, obj._name, res_id=obj_reference, context=context) + value = prop.get(cr, uid, prop_name, obj._name, res_id=obj_reference, context=context) if value: - res[id][prop] = value - # check existence as root (as seeing the name of a related + 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 res[id][prop] and property_field_type == 'many2one': - if not property_destination_obj: - property_destination_obj = res[id][prop]._name - if not obj.pool.get(res[id][prop]._name).exists(cr, 1, res[id][prop].id): - res[id][prop] = False - if property_destination_obj and property_field_type == 'many2one': + if res[id][prop_name] and property_destination_obj: + if obj.pool.get(property_destination_obj).exists(cr, 1, res[id][prop_name].id): + name_get_list_ids.append(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_list_ids = [res[id][prop].id for id in ids if res[id][prop]] name_get_values = dict(obj.pool.get(property_destination_obj).name_get(cr, 1, name_get_list_ids, context=context)) - #if the property field is a m2o, we need to return a tuple with (id, name) - for id in ids: - if res[id][prop] and isinstance(res[id][prop], orm.browse_record): - res[id][prop] = (res[id][prop].id , name_get_values.get(res[id][prop].id, False)) + # the property field is a m2o, we need to return a tuple with (id, name) + for id in name_get_values.keys(): + res[id][prop_name] = (res[id][prop_name].id , name_get_values.get(res[id][prop_name].id)) return res def _field_get(self, cr, uid, model_name, prop): diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 4c730c91c58..046e0d5ac46 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -1388,21 +1388,16 @@ def upload_data(email, data, type='SURVEY'): return True def get_and_group_by_field(cr, uid, obj, ids, field, context=None): - """Reads ``field´´ on given ``ids´´ and map all the ones that shares the same value. + """ 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 """ - value_fields = obj.read(cr, uid, ids, [field],context=context) res = {} - for item in value_fields: - key = item[field] - if isinstance(key,tuple): - key = key[0] - if not key in res: - res[key] = [] - res[key].append(item['id']) + 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): From 5265ceeffc641a36c4053b7af96905f22d9e34a5 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 11 Jul 2011 15:18:04 +0200 Subject: [PATCH 07/10] [IMP] fields.py: removed unnecessary initialization. bzr revid: vmt@openerp.com-20110711131804-1p9qk2j9zp2uuevy --- openerp/osv/fields.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index e16836e1163..89523dac70f 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1228,7 +1228,6 @@ class property(function): :rtype: dict """ prop = obj.pool.get('ir.property') - default_value = {}.fromkeys(prop_names, False) for prop_name in prop_names: default_value[prop_name] = prop.get(cr, uid, prop_name, obj._name, context=context) return default_value From e3725cb3a6981ce04d7f8442fc55c0419960396d Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 11 Jul 2011 16:25:03 +0200 Subject: [PATCH 08/10] [FIX] fields.property: set the m2o fields as False instead of browse_null. bzr revid: vmt@openerp.com-20110711142503-pokzph1wgo2j3223 --- openerp/osv/fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 89523dac70f..a6f14ca689a 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1298,8 +1298,8 @@ class property(function): # 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 res[id][prop_name] and property_destination_obj: - if obj.pool.get(property_destination_obj).exists(cr, 1, res[id][prop_name].id): + 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_list_ids.append(res[id][prop_name].id) else: res[id][prop_name] = False From cadfd7d85fdeb0881f6eb7acca77d0d43f24811c Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Mon, 11 Jul 2011 18:15:58 +0200 Subject: [PATCH 09/10] [FIX] fields.property: typos/misnamed variables. bzr revid: vmt@openerp.com-20110711161558-kac442kzcu3ujvj4 --- openerp/osv/fields.py | 21 +++++++++++---------- openerp/tools/misc.py | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index a6f14ca689a..4d098d3445f 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1228,9 +1228,10 @@ class property(function): :rtype: dict """ prop = obj.pool.get('ir.property') + res = {} for prop_name in prop_names: - default_value[prop_name] = prop.get(cr, uid, prop_name, obj._name, context=context) - return default_value + 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') @@ -1283,11 +1284,10 @@ class property(function): for prop_name in prop_names: property_field = obj._all_columns.get(prop_name).column - property_field_type = property_field.type - property_destination_obj = property_field.relation # false if type is not a many2one - # If the property field is a m2o field, we will append the id of the value to name_get_list_ids + 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_list_ids = [] + name_get_ids = {} for id in ids: # 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) @@ -1300,17 +1300,18 @@ class property(function): # 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_list_ids.append(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_list_ids, context=context)) + 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 id in name_get_values.keys(): - res[id][prop_name] = (res[id][prop_name].id , name_get_values.get(res[id][prop_name].id)) + 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): diff --git a/openerp/tools/misc.py b/openerp/tools/misc.py index 046e0d5ac46..20f168f11ab 100644 --- a/openerp/tools/misc.py +++ b/openerp/tools/misc.py @@ -1395,7 +1395,7 @@ def get_and_group_by_field(cr, uid, obj, ids, field, context=None): :rtype: dict """ res = {} - for record in obj.read(cr, uid, ids, [field], context=context) + 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 From 1f6833e708efacf6cc521e058c4e4deba5700cb2 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Tue, 12 Jul 2011 10:37:11 +0200 Subject: [PATCH 10/10] [IMP] fields.py: removed unused import (and cyclic dependency!). bzr revid: vmt@openerp.com-20110712083711-6serbntp8y5fn3qy --- openerp/osv/fields.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 4d098d3445f..056198a76d7 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1212,8 +1212,6 @@ class serialized(_column): self._symbol_get = self._deserialize_func super(serialized, self).__init__(string=string, **args) -import orm - # TODO: review completly this class for speed improvement class property(function):