diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 50588e9f3e9..96187c76a32 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -746,39 +746,45 @@ class IrModelFields(models.Model): fields_data = self._existing_field_data(field.model_name) field_data = fields_data.get(field.name) params = self._reflect_field_params(field) + cr = self.env.cr + created = False if field_data is None: - cr = self.env.cr - # create an entry in this table + # does not exist, create an entry in this table query_insert(cr, self._table, params) record = self.browse(cr.fetchone()) self.pool.post_init(record.modified, list(params)) - # create a corresponding xml id - module = field._module or self._context.get('module') - if module: - model_name = field.model_name.replace('.', '_') - xmlid = 'field_%s__%s' % (model_name, field.name) - cr.execute(""" INSERT INTO ir_model_data (module, name, model, res_id, date_init, date_update) - VALUES (%s, %s, %s, %s, (now() at time zone 'UTC'), (now() at time zone 'UTC')) """, - (module, xmlid, record._name, record.id)) # update fields_data (for recursive calls) fields_data[field.name] = dict(params, id=record.id) - return record + created = True - diff = {key for key, val in params.items() if field_data[key] != val} - if diff: - cr = self.env.cr - # update the entry in this table + elif any(field_data[key] != val for key, val in params.items()): + # exists, update the entry in this table query_update(cr, self._table, params, ['model', 'name']) record = self.browse(cr.fetchone()) - self.pool.post_init(record.modified, diff) + names = [key for key, val in params.items() if field_data[key] != val] + self.pool.post_init(record.modified, names) # update fields_data (for recursive calls) field_data.update(params) - return record else: - # nothing to update, simply return the corresponding record - return self.browse(field_data['id']) + # exists, but nothing to update + record = self.browse(field_data['id']) + + # generate xmlids if necessary, one per module defining the same field + module = self._context.get('module') + if module and (created or module in field._modules): + model_name = field.model_name.replace('.', '_') + xmlid = 'field_%s__%s' % (model_name, field.name) + cr.execute( + """ + INSERT INTO ir_model_data (module, name, model, res_id, date_init, date_update) + SELECT %s, %s, %s, %s, (now() at time zone 'UTC'), (now() at time zone 'UTC') + WHERE NOT EXISTS (SELECT id FROM ir_model_data WHERE module=%s AND name=%s) + """, (module, xmlid, record._name, record.id, module, xmlid) + ) + + return record def _reflect_model(self, model): """ Reflect the given model's fields. """ diff --git a/odoo/fields.py b/odoo/fields.py index e0ea484eb89..4050c07224c 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -272,8 +272,9 @@ class Field(MetaField('DummyField', (object,), {})): 'args': EMPTY_DICT, # the parameters given to __init__() '_attrs': EMPTY_DICT, # the field's non-slot attributes '_module': None, # the field's module name + '_modules': None, # modules that define this field '_setup_done': None, # the field's setup state: None, 'base' or 'full' - '_sequence': None, # absolute ordering of the field + '_sequence': None, # absolute ordering of the field 'automatic': False, # whether the field is automatically created ("magic" field) 'inherited': False, # whether the field is inherited (_inherits) @@ -391,16 +392,20 @@ class Field(MetaField('DummyField', (object,), {})): def _get_attrs(self, model, name): """ Return the field parameter attributes as a dictionary. """ # determine all inherited field attributes + modules = set() attrs = {} if not (self.args.get('automatic') or self.args.get('manual')): # magic and custom fields do not inherit from parent classes for field in reversed(resolve_mro(model, name, self._can_setup_from)): attrs.update(field.args) + if '_module' in field.args: + modules.add(field.args['_module']) attrs.update(self.args) # necessary in case self is not in class attrs['args'] = self.args attrs['model_name'] = model._name attrs['name'] = name + attrs['_modules'] = modules # initialize ``self`` with ``attrs`` if attrs.get('compute'):