在odoo 8中重写write()方法将导致运行时错误:超过最大递归深度

2024-05-08 09:24:25 发布

您现在位置:Python中文网/ 问答频道 /正文

这似乎是一个重大的简单问题,但不知何故我找不到解决办法。

当我按下save按钮时,write方法将被执行。每次调用write方法时,我都想更改当前模型的值(或调用函数),因此我已将模型的write()方法重写为

@api.multi
def write(self, vals):
    self.flaeche = 37
    return super(lager, self).write(vals)

(模型是lager.py,字段是flaeche = fields.Float(string=u"Fläche (m²)")

错误:RuntimeError: maximum recursion depth exceeded

Traceback (most recent call last):
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 530, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 567, in dispatch
    result = self._call_function(**self.params)
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 303, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/service/model.py", line 113, in wrapper
    return f(dbname, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 300, in checked_call
    return self.endpoint(*a, **kw)
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 796, in __call__
    return self.method(*args, **kw)
  File "/home/tertia/workspace/odoo8/openerp/http.py", line 396, in response_wrap
    response = f(*args, **kw)
  File "/home/tertia/workspace/odoo8/openerp/addons/web/controllers/main.py", line 936, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/home/tertia/workspace/odoo8/openerp/addons/web/controllers/main.py", line 928, in _call_kw
    return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 363, in old_api
    result = method(recs, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
    self.flaeche = 37
  File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
    record.write({self.name: self.convert_to_write(value)})
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
    return new_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
    self.flaeche = 37
  File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
    record.write({self.name: self.convert_to_write(value)})
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
    return new_api(self, *args, **kwargs)

.....

  File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
    self.flaeche = 37
  File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
    record.write({self.name: self.convert_to_write(value)})
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
    return new_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 225, in write
    self.flaeche = 37
  File "/home/tertia/workspace/odoo8/openerp/fields.py", line 853, in __set__
    record.write({self.name: self.convert_to_write(value)})
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
    return new_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/custom_modules/g4e_config/lager.py", line 224, in write
    super(lager, self).write(vals)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 239, in wrapper
    return new_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 546, in new_api
    result = method(self._model, cr, uid, self.ids, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/addons/mail/mail_thread.py", line 435, in write
    self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/addons/mail/mail_thread.py", line 1883, in message_auto_subscribe
    header_subtype_ids = subtype_obj.search(cr, uid, ['|', ('res_model', '=', False), ('parent_id.res_model', '=', self._name)], context=context)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 1639, in search
    return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 4621, in _search
    query = self._where_calc(cr, user, args, context=context)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 4444, in _where_calc
    e = expression.expression(cr, user, domain, self, context)
  File "/home/tertia/workspace/odoo8/openerp/osv/expression.py", line 646, in __init__
    self.parse(cr, uid, context=context)
  File "/home/tertia/workspace/odoo8/openerp/osv/expression.py", line 847, in parse
    right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 1639, in search
    return self._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 4615, in _search
    self.check_access_rights(cr, access_rights_uid or user, 'read')
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/models.py", line 3477, in check_access_rights
    return self.pool.get('ir.model.access').check(cr, uid, self._name, operation, raise_exception)
  File "/home/tertia/workspace/odoo8/openerp/api.py", line 241, in wrapper
    return old_api(self, *args, **kwargs)
  File "<string>", line 2, in check
  File "/home/tertia/workspace/odoo8/openerp/tools/cache.py", line 117, in lookup
    r = d[key]
  File "/home/tertia/workspace/odoo8/openerp/tools/func.py", line 66, in wrapper
    return func(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/tools/lru.py", line 38, in __getitem__
    self[a[0]] = a[1]
  File "/home/tertia/workspace/odoo8/openerp/tools/func.py", line 66, in wrapper
    return func(self, *args, **kwargs)
  File "/home/tertia/workspace/odoo8/openerp/tools/lru.py", line 44, in __setitem__
    del self[obj]

当我想调用lager模型的函数时,也会发生同样的情况。 我做错什么了?


Tags: inpyselfapihomereturnlineodoo8
3条回答

lager.write方法中,self.flaeche=37语句触发对field.__set__()的调用,该调用调用record.write()-record在这里是当前的lager实例,因此是无限递归。

我对odoo一无所知,但希望有一种方法可以在不触发对write的调用的情况下设置字段-否则,好吧,倒霉。

这样对我有效,调用祖先类:

@api.multi
def write(self, vals):
    vals['flaeche'] = 37
    return super(models.Model, self).write(vals)

当覆盖新模型而不是继承模型时,解决方案是适当的。

问题是,通过编写self.flaeche = 37,您正在更改记录,这意味着隐式调用模型上的write()方法。当从write()调用write()时,显然会以递归结束。

您可以执行类似的操作:

@api.multi
def write(self, vals):
    vals['flaeche'] = 37
    return super(lager, self).write(vals)

这样就不会有额外的写操作了—您只需更改即将发生的写操作的值。

如果要允许人们显式覆盖37的值,可以执行以下操作:

@api.multi
def write(self, vals):
    if 'flaeche' not in vals:
        vals['flaeche'] = 37
    return super(lager, self).write(vals)

相关问题 更多 >