diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 9314b1c3715..6221fb5928d 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1005,15 +1005,18 @@ class account_invoice(models.Model): #TODO: implement messages system return True - @api.one - def _compute_display_name(self): + @api.multi + def name_get(self): TYPES = { 'out_invoice': _('Invoice'), 'in_invoice': _('Supplier Invoice'), 'out_refund': _('Refund'), 'in_refund': _('Supplier Refund'), } - self.display_name = "%s %s" % (self.number or TYPES[self.type], self.name or '') + result = [] + for inv in self: + result.append((inv.id, "%s %s" % (inv.number or TYPES[inv.type], inv.name or ''))) + return result @api.model def name_search(self, name, args=None, operator='ilike', limit=100): diff --git a/addons/base_import/tests/test_cases.py b/addons/base_import/tests/test_cases.py index ac5a4440523..bad79bc7cdc 100644 --- a/addons/base_import/tests/test_cases.py +++ b/addons/base_import/tests/test_cases.py @@ -11,18 +11,10 @@ ID_FIELD = { 'required': False, 'fields': [], } -DISPLAY_NAME_FIELD = { - 'id': 'display_name', - 'name': 'display_name', - 'string': "Name", - 'required': False, - 'fields': [], -} def make_field(name='value', string='unknown', required=False, fields=[]): return [ ID_FIELD, - DISPLAY_NAME_FIELD, {'id': name, 'name': name, 'string': string, 'required': required, 'fields': fields}, ] @@ -50,7 +42,7 @@ class test_basic_fields(BaseImportCase): def test_readonly(self): """ Readonly fields should be filtered out""" - self.assertEqualFields(self.get_fields('char.readonly'), [ID_FIELD, DISPLAY_NAME_FIELD]) + self.assertEqualFields(self.get_fields('char.readonly'), [ID_FIELD]) def test_readonly_states(self): """ Readonly fields with states should not be filtered out""" @@ -59,12 +51,12 @@ class test_basic_fields(BaseImportCase): def test_readonly_states_noreadonly(self): """ Readonly fields with states having nothing to do with readonly should still be filtered out""" - self.assertEqualFields(self.get_fields('char.noreadonly'), [ID_FIELD, DISPLAY_NAME_FIELD]) + self.assertEqualFields(self.get_fields('char.noreadonly'), [ID_FIELD]) def test_readonly_states_stillreadonly(self): """ Readonly fields with readonly states leaving them readonly always... filtered out""" - self.assertEqualFields(self.get_fields('char.stillreadonly'), [ID_FIELD, DISPLAY_NAME_FIELD]) + self.assertEqualFields(self.get_fields('char.stillreadonly'), [ID_FIELD]) def test_m2o(self): """ M2O fields should allow import of themselves (name_get), @@ -92,7 +84,6 @@ class test_o2m(BaseImportCase): def test_shallow(self): self.assertEqualFields(self.get_fields('o2m'), make_field(fields=[ ID_FIELD, - DISPLAY_NAME_FIELD, # FIXME: should reverse field be ignored? {'id': 'parent_id', 'name': 'parent_id', 'string': 'unknown', 'required': False, 'fields': [ {'id': 'parent_id', 'name': 'id', 'string': 'External ID', 'required': False, 'fields': []}, @@ -250,7 +241,6 @@ class test_preview(TransactionCase): # Order depends on iteration order of fields_get self.assertItemsEqual(result['fields'], [ ID_FIELD, - DISPLAY_NAME_FIELD, {'id': 'name', 'name': 'name', 'string': 'Name', 'required':False, 'fields': []}, {'id': 'somevalue', 'name': 'somevalue', 'string': 'Some Value', 'required':True, 'fields': []}, {'id': 'othervalue', 'name': 'othervalue', 'string': 'Other Variable', 'required':False, 'fields': []}, diff --git a/addons/event/event.py b/addons/event/event.py index e5a12fb02d2..325682f86b3 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -185,12 +185,15 @@ class event_event(models.Model): for reg in self.registration_ids ) - @api.one + @api.multi @api.depends('name', 'date_begin', 'date_end') - def _compute_display_name(self): - dates = [dt.split(' ')[0] for dt in [self.date_begin, self.date_end] if dt] - dates = sorted(set(dates)) - self.display_name = '%s (%s)' % (self.name, ' - '.join(dates)) + def name_get(self): + result = [] + for event in self: + dates = [dt.split(' ')[0] for dt in [event.date_begin, event.date_end] if dt] + dates = sorted(set(dates)) + result.append((event.id, '%s (%s)' % (event.name, ' - '.join(dates)))) + return result @api.one @api.constrains('seats_max', 'seats_available') diff --git a/addons/website_forum_doc/models/documentation.py b/addons/website_forum_doc/models/documentation.py index c393f6eec56..655040fb16f 100644 --- a/addons/website_forum_doc/models/documentation.py +++ b/addons/website_forum_doc/models/documentation.py @@ -24,13 +24,13 @@ class Documentation(osv.Model): res.append((record['id'], name)) return res + # TODO master remove me def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None): res = self.name_get(cr, uid, ids, context=context) return dict(res) _columns = { 'sequence': fields.integer('Sequence'), - 'display_name': fields.function(_name_get_fnc, type="char", string='Full Name'), 'name': fields.char('Name', required=True, translate=True), 'introduction': fields.html('Introduction', translate=True), 'parent_id': fields.many2one('forum.documentation.toc', 'Parent Table Of Content', ondelete='cascade'), diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index cbbfabe9cb5..b0c32cdd77a 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -132,10 +132,15 @@ class ir_model(osv.osv): ('obj_name_uniq', 'unique (model)', 'Each model must be unique!'), ] - def _search_display_name(self, operator, value): - # overridden to allow searching both on model name (model field) and - # model description (name field) - return ['|', ('model', operator, value), ('name', operator, value)] + # overridden to allow searching both on model name (model field) + # and model description (name field) + def _name_search(self, cr, uid, name='', args=None, operator='ilike', context=None, limit=100, name_get_uid=None): + if args is None: + args = [] + domain = args + ['|', ('model', operator, name), ('name', operator, name)] + return self.name_get(cr, name_get_uid or uid, + super(ir_model, self).search(cr, uid, domain, limit=limit, context=context), + context=context) def _drop_table(self, cr, uid, ids, context=None): for model in self.browse(cr, uid, ids, context): @@ -806,20 +811,19 @@ class ir_model_data(osv.osv): """ _name = 'ir.model.data' _order = 'module,model,name' - def _display_name_get(self, cr, uid, ids, prop, unknow_none, context=None): + def name_get(self, cr, uid, ids, context=None): result = {} - result2 = {} + result2 = [] for res in self.browse(cr, uid, ids, context=context): if res.id: result.setdefault(res.model, {}) result[res.model][res.res_id] = res.id - result2[res.id] = False for model in result: try: r = dict(self.pool[model].name_get(cr, uid, result[model].keys(), context=context)) for key,val in result[model].items(): - result2[val] = r.get(key, False) + result2.append((val, r.get(key, False))) except: # some object have no valid name_get implemented, we accept this pass @@ -836,7 +840,6 @@ class ir_model_data(osv.osv): help="External Key/Identifier that can be used for " "data integration with third-party systems"), 'complete_name': fields.function(_complete_name_get, type='char', string='Complete ID'), - 'display_name': fields.function(_display_name_get, type='char', string='Record Name'), 'model': fields.char('Model Name', required=True, select=1), 'module': fields.char('Module', required=True, select=1), 'res_id': fields.integer('Record ID', select=1, diff --git a/openerp/addons/base/res/res_bank.py b/openerp/addons/base/res/res_bank.py index 7b3f8ec3743..84529f0080a 100644 --- a/openerp/addons/base/res/res_bank.py +++ b/openerp/addons/base/res/res_bank.py @@ -192,7 +192,7 @@ class res_partner_bank(osv.osv): def name_get(self, cr, uid, ids, context=None): if not len(ids): return [] - bank_dicts = self.read(cr, uid, ids, context=context) + bank_dicts = self.read(cr, uid, ids, self.fields_get_keys(cr, uid, context=context), context=context) return self._prepare_name_get(cr, uid, bank_dicts, context=context) def onchange_company_id(self, cr, uid, ids, company_id, context=None): diff --git a/openerp/models.py b/openerp/models.py index b6cad209f74..1b75bd2e05f 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -500,9 +500,8 @@ class BaseModel(object): # this field 'id' must override any other column or field cls._add_field('id', fields.Id(automatic=True)) - add('display_name', fields.Char(string='Name', - compute='_compute_display_name', inverse='_inverse_display_name', - search='_search_display_name', automatic=True)) + add('display_name', fields.Char(string='Display Name', automatic=True, + compute='_compute_display_name')) if cls._log_access: add('create_uid', fields.Many2one('res.users', string='Created by', automatic=True)) @@ -1648,30 +1647,8 @@ class BaseModel(object): @api.depends(lambda self: (self._rec_name,) if self._rec_name else ()) def _compute_display_name(self): - name = self._rec_name - if name in self._fields: - convert = self._fields[name].convert_to_display_name - for record in self: - record.display_name = convert(record[name]) - else: - for record in self: - record.display_name = "%s,%s" % (record._name, record.id) - - def _inverse_display_name(self): - name = self._rec_name - if name in self._fields and not self._fields[name].relational: - for record in self: - record[name] = record.display_name - else: - _logger.warning("Cannot inverse field display_name on %s", self._name) - - def _search_display_name(self, operator, value): - name = self._rec_name - if name in self._fields: - return [(name, operator, value)] - else: - _logger.warning("Cannot search field display_name on %s", self._name) - return [(0, '=', 1)] + for i, got_name in enumerate(self.name_get()): + self[i].display_name = got_name[1] @api.multi def name_get(self): @@ -1682,11 +1659,15 @@ class BaseModel(object): :return: list of pairs ``(id, text_repr)`` for all records """ result = [] - for record in self: - try: - result.append((record.id, record.display_name)) - except MissingError: - pass + name = self._rec_name + if name in self._fields: + convert = self._fields[name].convert_to_display_name + for record in self: + result.append((record.id, convert(record[name]))) + else: + for record in self: + result.append((record.id, "%s,%s" % (record._name, record.id))) + return result @api.model @@ -1702,13 +1683,12 @@ class BaseModel(object): :rtype: tuple :return: the :meth:`~.name_get` pair value of the created record """ - # Shortcut the inverse function of 'display_name' with self._rec_name. - # This is useful when self._rec_name is a required field: in that case, - # create() creates a record without the field, and inverse display_name - # afterwards. - field_name = self._rec_name if self._rec_name else 'display_name' - record = self.create({field_name: name}) - return (record.id, record.display_name) + if self._rec_name: + record = self.create({self._rec_name: name}) + return record.name_get()[0] + else: + _logger.warning("Cannot execute name_create, no _rec_name defined on %s", self._name) + return False @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): @@ -1734,8 +1714,10 @@ class BaseModel(object): :return: list of pairs ``(id, text_repr)`` for all matching records. """ args = list(args or []) - if not (name == '' and operator == 'ilike'): - args += [('display_name', operator, name)] + if not self._rec_name: + _logger.warning("Cannot execute name_search, no _rec_name defined on %s", self._name) + elif not (name == '' and operator == 'ilike'): + args += [(self._rec_name, operator, name)] return self.search(args, limit=limit).name_get() def _name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=100, name_get_uid=None): @@ -1743,8 +1725,10 @@ class BaseModel(object): # for the name_get part to solve some access rights issues args = list(args or []) # optimize out the default criterion of ``ilike ''`` that matches everything - if not (name == '' and operator == 'ilike'): - args += [('display_name', operator, name)] + if not self._rec_name: + _logger.warning("Cannot execute name_search, no _rec_name defined on %s", self._name) + elif not (name == '' and operator == 'ilike'): + args += [(self._rec_name, operator, name)] access_rights_uid = name_get_uid or user ids = self._search(cr, user, args, limit=limit, context=context, access_rights_uid=access_rights_uid) res = self.name_get(cr, access_rights_uid, ids, context)