[IMP] fields: avoid __set__ multiple loops on record, and new browse records
This patch avoids to create new browse records for nothing, (as creating new browse (__new__) is costly), and to avoid to loop multiple times on the records (with multiple different filtered, etc.) This brings performance gain to __set__, which is used when setting the value of a compute field e.g. This improves the performances of `env['product.product'].search_read([])` closes odoo/odoo#36006 Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
committed by
Raphael Collet
parent
3d1c924cff
commit
5cac9c54ff
+19
-9
@@ -1070,24 +1070,34 @@ class Field(MetaField('DummyField', (object,), {})):
|
||||
|
||||
def __set__(self, records, value):
|
||||
""" set the value of field ``self`` on ``records`` """
|
||||
protected_records = records & records.env.protected(self)
|
||||
if protected_records:
|
||||
# records being computed: no business logic, no recomputation
|
||||
self.write(protected_records, value)
|
||||
records -= protected_records
|
||||
protected_ids = []
|
||||
new_ids = []
|
||||
other_ids = []
|
||||
for record_id in records._ids:
|
||||
if record_id in records.env._protected.get(self, ()):
|
||||
protected_ids.append(record_id)
|
||||
elif not record_id:
|
||||
new_ids.append(record_id)
|
||||
else:
|
||||
other_ids.append(record_id)
|
||||
|
||||
new_records = records.filtered(lambda record: not record.id)
|
||||
if new_records:
|
||||
if protected_ids:
|
||||
# records being computed: no business logic, no recomputation
|
||||
protected_records = records.browse(protected_ids)
|
||||
self.write(protected_records, value)
|
||||
|
||||
if new_ids:
|
||||
# new records: no business logic
|
||||
new_records = records.browse(new_ids)
|
||||
with records.env.protecting(records._field_computed.get(self, [self]), records):
|
||||
new_records.modified([self.name])
|
||||
self.write(new_records, value)
|
||||
if self.relational:
|
||||
new_records.modified([self.name])
|
||||
records -= new_records
|
||||
|
||||
if records:
|
||||
if other_ids:
|
||||
# base case: full business logic
|
||||
records = records.browse(other_ids)
|
||||
write_value = self.convert_to_write(value, records)
|
||||
records.write({self.name: write_value})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user