[IMP] base: perf - try/except instead of exists

Most of the time, the record exists, but we still ensure it does, every single
time, making an SQL query.
Doing a try catch will result in the same behavior, but won't make that query
most of the time.

task-2211013
This commit is contained in:
Romain Derie
2020-03-26 18:12:47 +00:00
parent 2c09e00a64
commit bd4a44cece
2 changed files with 34 additions and 31 deletions
+5 -5
View File
@@ -32,15 +32,15 @@ class TestStandardPerformance(UtilPerf):
def test_10_perf_sql_img_controller(self):
self.authenticate('demo', 'demo')
url = '/web/image/res.country/4/image'
self.assertEqual(self._get_url_hot_query(url), 5)
self.assertEqual(self._get_url_hot_query(url), 4)
url = '/web/image/res.users/2/image_256'
self.assertEqual(self._get_url_hot_query(url), 8)
self.assertEqual(self._get_url_hot_query(url), 7)
def test_20_perf_sql_img_controller_bis(self):
url = '/web/image/website/1/favicon'
self.assertEqual(self._get_url_hot_query(url), 6)
self.authenticate('portal', 'portal')
self.assertEqual(self._get_url_hot_query(url), 5)
self.authenticate('portal', 'portal')
self.assertEqual(self._get_url_hot_query(url), 4)
class TestWebsitePerformance(UtilPerf):
@@ -119,4 +119,4 @@ class TestWebsitePerformance(UtilPerf):
# assets route /web/content/..
self.url_open('/') # create assets attachments
assets_url = self.env['ir.attachment'].search([('url', '=like', '/web/content/%/web.assets_common%.js')], limit=1).url
self.assertEqual(self._get_url_hot_query(assets_url), 5)
self.assertEqual(self._get_url_hot_query(assets_url), 4)
+29 -26
View File
@@ -19,7 +19,7 @@ import werkzeug.utils
import odoo
from odoo import api, http, models, tools, SUPERUSER_ID
from odoo.exceptions import AccessDenied, AccessError
from odoo.exceptions import AccessDenied, AccessError, MissingError
from odoo.http import request, content_disposition
from odoo.tools import consteq, pycompat
from odoo.tools.mimetypes import guess_mimetype
@@ -296,35 +296,38 @@ class IrHttp(models.AbstractModel):
record = self.env[model].browse(int(id))
# obj exists
if not record or not record.exists() or field not in record:
if not record or field not in record:
return None, 404
if model == 'ir.attachment':
record_sudo = record.sudo()
if access_token and not consteq(record_sudo.access_token or '', access_token):
return None, 403
elif (access_token and consteq(record_sudo.access_token or '', access_token)):
record = record_sudo
elif record_sudo.public:
record = record_sudo
elif self.env.user.has_group('base.group_portal'):
# Check the read access on the record linked to the attachment
# eg: Allow to download an attachment on a task from /my/task/task_id
record.check('read')
record = record_sudo
# check read access
try:
# We have prefetched some fields of record, among which the field
# 'write_date' used by '__last_update' below. In order to check
# access on record, we have to invalidate its cache first.
if not record.env.su:
record._cache.clear()
record['__last_update']
except AccessError:
return None, 403
if model == 'ir.attachment':
record_sudo = record.sudo()
if access_token and not consteq(record_sudo.access_token or '', access_token):
return None, 403
elif (access_token and consteq(record_sudo.access_token or '', access_token)):
record = record_sudo
elif record_sudo.public:
record = record_sudo
elif self.env.user.has_group('base.group_portal'):
# Check the read access on the record linked to the attachment
# eg: Allow to download an attachment on a task from /my/task/task_id
record.check('read')
record = record_sudo
return record, 200
# check read access
try:
# We have prefetched some fields of record, among which the field
# 'write_date' used by '__last_update' below. In order to check
# access on record, we have to invalidate its cache first.
if not record.env.su:
record._cache.clear()
record['__last_update']
except AccessError:
return None, 403
return record, 200
except MissingError:
return None, 404
@classmethod
def _binary_ir_attachment_redirect_content(cls, record, default_mimetype='application/octet-stream'):