I’ve been hooking into the OpenERP ORM layer of a few of the models to add full text search via an external engine. Thanks to the way OpenERP is structured that appears to be quite a reliable approach. As I was doing it I found that I wanted a common set of hooks on several models. Doing that suggested I should refactor the hooks to a mixin or a base class. After playing about with my OpenERP module I’ve come to the conclusion that creating a base class seems to be the most reliable way to hook the methods. The one trick you need to be aware of is the _register flag that you want to set to False for your base class.
class search_base(osv.osv):
_register = False
def write(self, cr, user, ids, vals, context=None):
success = super(search_base, self).write(cr, user, ids,
vals, context)
… do stuff
return success
class product_template_search(search_base):
_name = "product.template"
_inherit = "product.template"
_register = True
class product_search(search_base):
_name = "product.product"
_inherit = "product.product"
_register = True
product_search()
product_template_search()
Without that you’ll end up with the orm whining that the search_base class has no _name attribute as it tries to register it as a model.
openerp.osv.orm: The class search_base has to have a _name attribute
openerp.netsvc: ValueError
The class search_base has to have a _name attribute
> /usr/lib/pymodules/python2.7/openerp/osv/orm.py(967)__init__()
-> raise except_orm('ValueError', msg)


Why not just follow what is done in standard modules, like crm.case:
class product_template_search(search_base, osv.osv)
This doesn’t rely on internal implementations of the ORM that could be changed in newer versions.
To tell the truth I was going to do that, but it didn’t appear to work. I think I may have just realised why however. I’ll have to give it another go. Thanks for pointing that example out.