Skip to content

Commit b0f48ca

Browse files
committed
[IMP] fs_attachment: simplify domain for attachment search by skipping res_field checks
1 parent 3952ed1 commit b0f48ca

3 files changed

Lines changed: 34 additions & 26 deletions

File tree

fs_attachment/models/fs_storage.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -310,19 +310,14 @@ def recompute_urls(self) -> None:
310310
in staging are done in a different directory and will not impact the
311311
production.
312312
"""
313-
# The weird "res_field = False OR res_field != False" domain
314-
# is required! It's because of an override of _search in ir.attachment
315-
# which adds ('res_field', '=', False) when the domain does not
316-
# contain 'res_field'.
317-
# https://github.com/odoo/odoo/blob/9032617120138848c63b3cfa5d1913c5e5ad76db/
318-
# odoo/addons/base/ir/ir_attachment.py#L344-L347
319313
domain = [
320314
("fs_storage_id", "in", self.ids),
321-
"|",
322-
("res_field", "=", False),
323-
("res_field", "!=", False),
324315
]
325-
attachments = self.env["ir.attachment"].search(domain)
316+
attachments = (
317+
self.env["ir.attachment"]
318+
.with_context(skip_res_field_check=True)
319+
.search(domain)
320+
)
326321
attachments._compute_fs_url()
327322
attachments._compute_fs_url_path()
328323

fs_attachment/models/ir_attachment.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -767,19 +767,16 @@ def force_storage_to_db_for_special_fields(
767767
normalize_domain(
768768
[
769769
("store_fname", "=like", f"{storage}://%"),
770-
# for res_field, see comment in
771-
# _force_storage_to_object_storage
772-
"|",
773-
("res_field", "=", False),
774-
("res_field", "!=", False),
775770
]
776771
),
777772
normalize_domain(self._store_in_db_instead_of_object_storage_domain()),
778773
)
779774
)
780775

781776
with self._do_in_new_env(new_cr=new_cr) as new_env:
782-
model_env = new_env["ir.attachment"].with_context(prefetch_fields=False)
777+
model_env = new_env["ir.attachment"].with_context(
778+
prefetch_fields=False, skip_res_field_check=True
779+
)
783780
attachment_ids = model_env.search(domain).ids
784781
if not attachment_ids:
785782
return
@@ -819,25 +816,16 @@ def _force_storage_to_object_storage(self, new_cr=False):
819816
storage = self.env.context.get("storage_location") or self._storage()
820817
if self._is_storage_disabled(storage):
821818
return
822-
# The weird "res_field = False OR res_field != False" domain
823-
# is required! It's because of an override of _search in ir.attachment
824-
# which adds ('res_field', '=', False) when the domain does not
825-
# contain 'res_field'.
826-
# https://github.com/odoo/odoo/blob/9032617120138848c63b3cfa5d1913c5e5ad76db/
827-
# odoo/addons/base/ir/ir_attachment.py#L344-L347
828819
domain = [
829820
"!",
830821
("store_fname", "=like", f"{storage}://%"),
831-
"|",
832-
("res_field", "=", False),
833-
("res_field", "!=", False),
834822
]
835823
# We do a copy of the environment so we can workaround the cache issue
836824
# below. We do not create a new cursor by default because it causes
837825
# serialization issues due to concurrent updates on attachments during
838826
# the installation
839827
with self._do_in_new_env(new_cr=new_cr) as new_env:
840-
model_env = new_env["ir.attachment"]
828+
model_env = new_env["ir.attachment"].with_context(skip_res_field_check=True)
841829
ids = model_env.search(domain).ids
842830
files_to_clean = []
843831
for attachment_id in ids:

fs_attachment/tests/test_fs_attachment.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,24 +337,44 @@ def test_force_storage_to_db(self):
337337
attachment = self.ir_attachment_model.create(
338338
{"name": "test.txt", "raw": b"content"}
339339
)
340+
attachment_res_field = self.ir_attachment_model.create(
341+
{
342+
"name": "field.txt",
343+
"raw": "Attachment linked to a field",
344+
"res_model": "res.partner",
345+
"res_field": "name",
346+
}
347+
)
340348
self.env.flush_all()
341349
self.assertTrue(attachment.store_fname)
342350
self.assertFalse(attachment.db_datas)
343351
store_fname = attachment.store_fname
352+
store_fname_res_field = attachment_res_field.store_fname
344353
# we change the rules to force the storage in db for text/plain
345354
self.temp_backend.force_db_for_default_attachment_rules = '{"text/plain": 0}'
346355
attachment.force_storage_to_db_for_special_fields()
347356
self.assertFalse(attachment.store_fname)
348357
self.assertEqual(attachment.db_datas, b"content")
358+
self.assertFalse(attachment_res_field.store_fname)
359+
self.assertEqual(attachment_res_field.db_datas, b"Attachment linked to a field")
349360
# we check that the file is marked for GC
350361
gc_files = self.gc_file_model.search([]).mapped("store_fname")
351362
self.assertIn(store_fname, gc_files)
363+
self.assertIn(store_fname_res_field, gc_files)
352364

353365
@mute_logger("odoo.addons.fs_attachment.models.ir_attachment")
354366
def test_force_storage_to_fs(self):
355367
attachment = self.ir_attachment_model.create(
356368
{"name": "test.txt", "raw": b"content"}
357369
)
370+
attachment_res_field = self.ir_attachment_model.create(
371+
{
372+
"name": "field.txt",
373+
"raw": "Attachment linked to a field",
374+
"res_model": "res.partner",
375+
"res_field": "name",
376+
}
377+
)
358378
self.env.flush_all()
359379
fs_path = self.ir_attachment_model._filestore() + "/" + attachment.store_fname
360380
self.assertTrue(os.path.exists(fs_path))
@@ -371,8 +391,13 @@ def test_force_storage_to_fs(self):
371391
clean_fs.assert_called_once()
372392
# files into the filestore must be moved to our filesystem storage
373393
filename = f"test-{attachment.id}-0.txt"
394+
filename_res_field = f"field-{attachment_res_field.id}-0.txt"
374395
self.assertEqual(attachment.store_fname, f"tmp_dir://{filename}")
396+
self.assertEqual(
397+
attachment_res_field.store_fname, f"tmp_dir://{filename_res_field}"
398+
)
375399
self.assertIn(filename, os.listdir(self.temp_dir))
400+
self.assertIn(filename_res_field, os.listdir(self.temp_dir))
376401

377402
def test_storage_use_filename_obfuscation(self):
378403
self.temp_backend.base_url = "https://acsone.eu/media"

0 commit comments

Comments
 (0)