Search code examples
odooodoo-14

How to extend search record to also look at custom Many2Many field(s)?


In this image, there is a product search record that will search for name and default_code. I need to make it so that it will also look at my custom Many2Many field.

Search Product

This is the field in the inherited model.

product_list = fields.Many2many("product.list", string="Product List")

The custom model only has _name, _description, and name variables.

The question is how to make the search to also look at all of the possible Many2Many data of this field.

I have tried this in the inherited model:

@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
    res = super(product_template_inherit, self).name_search(name='', args=None, operator='ilike', limit=100)
    ids = self.search(args + [(name, 'in', 'product_list.name')], limit=limit)
    if ids:
        return ids.name_get()
    return res

Nothing happens to the search. It still searches using the same behavior regardless of the code above.

Summary: I need to be able to search product by product list (custom Many2Many field inherited in the product.template model)

=============================================

UPDATE

Current code from what I have been trying is now this.

@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
    args = args or []
    if operator == 'ilike' and not (name or '').strip():
        domain = []
    else:
        domain = ['|', ('name', 'ilike', name), ('product_list.name', 'ilike', name)]
        product_ids = self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
    return self.browse(product_ids).name_get()

However, it looks like it still searches using the same old fields. It does not change to behave as my function is written.


Solution

  • You can compute the search domain then return the result of the _search method.

    The fleet module already uses the same logic to search vehicles using the driver name, you have just to replace the driver_id with product_list:

    class ProductProduct(models.Model):
        _inherit = 'product.product'
    
        @api.model
        def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
            args = args or []
            if operator == 'ilike' and not (name or '').strip():
                domain = []
            else:
                domain = ['|', ('name', operator, name), ('product_list.name', operator, name)]
            return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)