[IMP] product: product & template name_get performance
By prefetching only the fields required for the `name_get` `product.product` & `product.template` have a huge number of fields, and prefetching them just to compute the name is overkill. Especially, as the browse was done using sudo, the prefetch was a bit useless as it was stored in the sudo user cache, which was most-likely not used afterwards by the callee of name_get For a database with 50.000 products, this reduce the processing time by 15 (from 60 seconds to 4 seconds measured)
This commit is contained in:
@@ -395,17 +395,36 @@ class ProductProduct(models.Model):
|
||||
self.check_access_rule("read")
|
||||
|
||||
result = []
|
||||
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
# Use `load=False` to not call `name_get` for the `product_tmpl_id`
|
||||
self.sudo().read(['name', 'default_code', 'product_tmpl_id', 'attribute_value_ids'], load=False)
|
||||
|
||||
product_template_ids = [product.product_tmpl_id.id for product in self]
|
||||
|
||||
if partner_ids:
|
||||
supplier_info = self.env['product.supplierinfo'].sudo().search([
|
||||
('product_tmpl_id', 'in', product_template_ids),
|
||||
('name', 'in', partner_ids),
|
||||
])
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
# Use `load=False` to not call `name_get` for the `product_tmpl_id` and `product_id`
|
||||
supplier_info.sudo().read(['product_tmpl_id', 'product_id', 'product_name', 'product_code'], load=False)
|
||||
supplier_info_by_template = {}
|
||||
for r in supplier_info:
|
||||
supplier_info_by_template.setdefault(r.product_tmpl_id, []).append(r)
|
||||
for product in self.sudo():
|
||||
# display only the attributes with multiple possible values on the template
|
||||
variable_attributes = product.attribute_line_ids.filtered(lambda l: len(l.value_ids) > 1).mapped('attribute_id')
|
||||
variable_attributes = product.attribute_value_ids.filtered(lambda v: len(v.attribute_id.value_ids) > 1).mapped('attribute_id')
|
||||
variant = product.attribute_value_ids._variant_name(variable_attributes)
|
||||
|
||||
name = variant and "%s (%s)" % (product.name, variant) or product.name
|
||||
sellers = []
|
||||
if partner_ids:
|
||||
sellers = [x for x in product.seller_ids if (x.name.id in partner_ids) and (x.product_id == product)]
|
||||
product_supplier_info = supplier_info_by_template.get(product.product_tmpl_id, [])
|
||||
sellers = [x for x in product_supplier_info if x.product_id and x.product_id == product]
|
||||
if not sellers:
|
||||
sellers = [x for x in product.seller_ids if (x.name.id in partner_ids) and not x.product_id]
|
||||
sellers = [x for x in product_supplier_info if not x.product_id]
|
||||
if sellers:
|
||||
for s in sellers:
|
||||
seller_variant = s.product_name and (
|
||||
|
||||
@@ -306,6 +306,8 @@ class ProductTemplate(models.Model):
|
||||
|
||||
@api.multi
|
||||
def name_get(self):
|
||||
# Prefetch the fields used by the `name_get`, so `browse` doesn't fetch other fields
|
||||
self.read(['name', 'default_code'])
|
||||
return [(template.id, '%s%s' % (template.default_code and '[%s] ' % template.default_code or '', template.name))
|
||||
for template in self]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user