如何在Odoo11的现有字段中添加新的自定义属性?

时间:2019-08-21 08:15:49

标签: python odoo

假设我要为现有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类属性?

0 个答案:

没有答案