[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
This commit is contained in:
committed by
Thibault Delavallée
parent
2fcb3c658d
commit
de7c119e66
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user