diff options
| author | Xavier-Do <xdo@odoo.com> | 2019-04-12 13:21:18 +0000 |
|---|---|---|
| committer | Thibault Delavallée <tde@odoo.com> | 2019-05-29 13:34:32 +0000 |
| commit | de7c119e666d108564b3889d1c08e5bf2e4da082 (patch) | |
| tree | 3c24844df7072ba840d93fb1f2b141ad7a507fa3 /odoo/addons/base/models/ir_attachment.py | |
| parent | 2fcb3c658df3e504b92ff9b5a805d150cfa7effd (diff) | |
[IMP] mail: reduce message_post query count and clean code
Purpose of this commit is to improve performance of post and notify through
various code improvements.
Containing
* making of _notify_customize_recipients a mail.thread method;
* _message_auto_subscribe_followers optimized;
* renaming and optimisation of _notify_partners;
* message_post_attachements optization;
* remove unused mail_post_autofollow_partner_ids context key;
* minimize message create queries;
* only check record related access right for thread messages not in pending
moderation;
* get attachements from values instead of db;
* storing lang in ctx from the beginning;
* don't track on write on attachments;
Related to task 1943901
Linked to PR #32404
Diffstat (limited to 'odoo/addons/base/models/ir_attachment.py')
| -rw-r--r-- | odoo/addons/base/models/ir_attachment.py | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/odoo/addons/base/models/ir_attachment.py b/odoo/addons/base/models/ir_attachment.py index a3176dccef8..ce98ee7c296 100644 --- a/odoo/addons/base/models/ir_attachment.py +++ b/odoo/addons/base/models/ir_attachment.py @@ -11,7 +11,7 @@ from collections import defaultdict import uuid from odoo import api, fields, models, tools, SUPERUSER_ID, _ -from odoo.exceptions import AccessError, ValidationError +from odoo.exceptions import AccessError, ValidationError, MissingError from odoo.tools import config, human_size, ustr, html_escape from odoo.tools.mimetypes import guess_mimetype @@ -313,6 +313,8 @@ class IrAttachment(models.Model): def _check_serving_attachments(self): # restrict writing on attachments that could be served by the # ir.http's dispatch exception handling + # XDO note: this should be done in check(write), constraints for access rights? + # XDO note: if read on sudo, read twice, one for constraints, one for _inverse_datas as user if self.env.user._is_admin(): return if self.type == 'binary' and self.url: @@ -326,13 +328,15 @@ class IrAttachment(models.Model): In the 'document' module, it is overriden to relax this hard rule, since more complex ones apply there. """ + if self.env.user._is_superuser(): + return True # collect the records to check (by model) model_ids = defaultdict(set) # {model_name: set(ids)} require_employee = False if self: self._cr.execute('SELECT res_model, res_id, create_uid, public, res_field FROM ir_attachment WHERE id IN %s', [tuple(self.ids)]) for res_model, res_id, create_uid, public, res_field in self._cr.fetchall(): - if self.env.user.id != SUPERUSER_ID and not self.env.user._is_system() and res_field: + if not self.env.user._is_system() and res_field: raise AccessError(_("Sorry, you are not allowed to access this document.")) if public and mode == 'read': continue @@ -488,12 +492,20 @@ class IrAttachment(models.Model): @api.model_create_multi def create(self, vals_list): + record_tuple_set = set() for values in vals_list: # remove computed field depending of datas for field in ('file_size', 'checksum'): values.pop(field, False) values = self._check_contents(values) - self.browse().check('write', values=values) + # 'check()' only uses res_model and res_id from values, and make an exists. + # We can group the values by model, res_id to make only one query when + # creating multiple attachments on a single record. + record_tuple = (values.get('res_model'), values.get('res_id')) + record_tuple_set.add(record_tuple) + for record_tuple in record_tuple_set: + (res_model, res_id) = record_tuple + self.check('write', values={'res_model':res_model, 'res_id':res_id}) return super(IrAttachment, self).create(vals_list) @api.multi @@ -504,10 +516,13 @@ class IrAttachment(models.Model): def generate_access_token(self): if self.access_token: return self.access_token - access_token = str(uuid.uuid4()) + access_token = self._generate_access_token() self.write({'access_token': access_token}) return access_token + def _generate_access_token(self): + return str(uuid.uuid4()) + @api.model def action_get(self): return self.env['ir.actions.act_window'].for_xml_id('base', 'action_attachment') |
