假设我要为现有Field
类添加新的自定义属性。特别是,我想向字段my_attr
添加一个属性(我们将其称为Many2one
),以便在将此类字段添加到Odoo模型时可以使用它:
from odoo import fields, models
class MyModel(models.Model):
_name = 'my.model'
my_field = fields.Many2one(
'my.comodel',
my_attr='something',
string="My field"
)
我试图覆盖类的__init__
,_get_attrs
,_setup_attrs
方法,并将此类属性添加到__slots__
和_slots
中;我什至尝试对基类Field
进行猴子补丁,就像在模块base_sparse_field from the Odoo addons中所做的一样:
from odoo import fields
def monkey_patch(cls):
""" Return a method decorator to monkey-patch the given class. """
def decorate(func):
name = func.__name__
func.super = getattr(cls, name, None)
setattr(cls, name, func)
return func
return decorate
@monkey_patch(fields.Field)
def _get_attrs(self, model, name):
attrs = _get_attrs.super(self, model, name)
if self.type == 'many2one' and attrs.get('my_attr'):
# Do stuff
elif attrs.get('my_attr'):
fields._logger.warning(
_("Cannot set `my_attr` attribute upon a field that's not"
" of type `Many2one`.")
)
attrs['my_attr'] = None
return attrs
_slots = fields.Many2one._slots
_slots.update({'my_attr': None})
fields.Many2one._slots = _slots
但是,一旦我使用此新属性启动Odoo,这就是我得到的错误:
Traceback (most recent call last):
File "/opt/odoo/odoo/odoo/service/server.py", line 945, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "/opt/odoo/odoo/odoo/modules/registry.py", line 85, in new
odoo.modules.load_modules(registry._db, force_demo, status, update_module)
File "/opt/odoo/odoo/odoo/modules/loading.py", line 376, in load_modules
force, status, report, loaded_modules, update_module, models_to_check)
File "/opt/odoo/odoo/odoo/modules/loading.py", line 274, in load_marked_modules
perform_checks=perform_checks, models_to_check=models_to_check
File "/opt/odoo/odoo/odoo/modules/loading.py", line 152, in load_module_graph
registry.setup_models(cr)
File "/opt/odoo/odoo/odoo/modules/registry.py", line 274, in setup_models
model._setup_base()
File "/opt/odoo/odoo/odoo/models.py", line 2393, in _setup_base
self._add_field(name, field.new())
File "/opt/odoo/odoo/odoo/models.py", line 290, in _add_field
field.setup_base(self, name)
File "/opt/odoo/odoo/odoo/fields.py", line 379, in setup_base
self._setup_attrs(model, name)
File "/opt/odoo/odoo/odoo/fields.py", line 1920, in _setup_attrs
super(Many2one, self)._setup_attrs(model, name)
File "/opt/odoo/odoo/odoo/fields.py", line 436, in _setup_attrs
self.set_all_attrs(attrs)
File "/opt/odoo/odoo/odoo/fields.py", line 350, in set_all_attrs
assign(self, key, attrs.pop(key, val))
AttributeError: 'Many2one' object has no attribute 'my_attr'
之所以会这样,是因为,正如您从the set_all_attrs
code所看到的那样,Odoo试图分配属性my_attr
(从_slots
字典中获取)。
但是,如果我从这样的字典中删除它,它将不会被解析或分配给任何字段。
我应该如何定义这个新属性,以便可以将其设置为正确的Many2one
类属性?