2015-09-21 9 views
6

To wydaje się być znaczącym, prostym problemem, ale jakoś nie mogę znaleźć rozwiązania.przesłanianie metody write() w odoo 8 wyników w RuntimeError: maksymalna głębokość rekursji przekroczyła

Po naciśnięciu przycisku zapisu zostanie wykonana metoda zapisu. Chcę zmienić wartość (lub wywołania funkcji) bieżącego modelu za każdym razem metoda zapisu jest nazywany, więc mam przesłonięte metody write() w moim modelu jako

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

(model jest lager.py i pole jest flaeche = fields.Float(string=u"Fläche (m²)"))

błąd: 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] 

to samo dzieje się, gdy chcę wywołać funkcję modelu lager. Co robię źle?

Odpowiedz

4

Problem polega na tym, że pisząc self.flaeche = 37 zmieniasz rekord, co oznacza niejawnie wywołanie metody write() na modelu. Gdy zadzwonisz pod numer write() z write(), prawdopodobnie skończysz z rekursją.

Można zrobić coś podobnego do tego, zamiast:

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

ten sposób istnieją żadne dodatkowe zapisy - wystarczy zmienić wartości dla napisać, że miało się wydarzyć w każdym razie.

Jeśli chcesz, aby umożliwić ludziom wyraźnie nadpisać wartość 37 można to zrobić:

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

Dzięki! to jest to! –

2

W swojej metodzie lager.write, oświadczenie self.flaeche=37 powoduje wywołanie field.__set__() który wzywa record.write() - record jest tutaj obecny lager instancji, stąd swojej nieskończonej rekurencji.

Nie wiem nic o zoo, ale mam nadzieję, że musi istnieć sposób na ustawienie pola bez wywoływania połączenia z write - w przeciwnym razie, pech.

1

ten sposób działa na mnie, nazywając klasę przodka:

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

Rozwiązaniem jest odpowiednie, gdy nadpisujesz nowy model, a nie dziedziczony.

+0

Nie widzę, jak byłoby to konieczne. Każdy model dziedziczy po 'models.Model', więc nie ma czegoś takiego jak" model nie odziedziczony ". –

Powiązane problemy