2015-11-07 69 views
1

我正在研究Odoo模塊,而不是直接在模型中定義字段時,我有一個名爲schema的元組,其中包含所有字段。我在模型中定義了一個從元組中讀取每個字段的類方法,並通過內省在模型中創建它。Odoo-9:通過setattr添加字段時,「RuntimeError:最大遞歸深度超過」

@classmethod 
def initialze(cls, schema): 
    for field in schema: 
     add_a_field(cls, field) 
     pass 
    pass  

如可以看到的,這個方法是迭代的元組和單獨的場傳遞給另一個方法名「add_a_field(CLS,場)」。

方法'add_a_field'使用python setattr()內置方法。

def add_a_field(cls, field): 
    setattr(cls, field.string, field) 
    pass 

它添加一個具有相同名稱和標籤的字段。

在我有這樣的方法我直接調用它爲下面的樣品中的類:

from openerp import fields, models 
# other imports 

def add_a_field(cls, field): 
    setattr(cls, field.string, field) 
    pass 

schema = (
      fields.Char(string='RequestID'), 
      fields.Float(string='Discount', default=0.00), 
      fields.Float(string='Subtotal', default=0.00), 
     ) 

class Batch(models.Model): 
    _name='batch' 
    @classmethod 
    def initialze(cls, schema): 
     for field in schema: 
      add_a_field(cls, field) 
      pass 
     pass  
    pass 

# other model methods 
Batch.initialze(schema) 

在Odoo V8中工作正常,但在V9它給出了一個錯誤「」 RuntimeError:最大遞歸深度超過」

在Odoo V9 fields.py __getattr__定義如下(見https://github.com/odoo/odoo/blob/9.0/openerp/fields.py):

def __getattr__(self, name): 
    """ Access non-slot field attribute. """ 
    try: 
     return self._attrs[name] 
    except KeyError: 
     raise AttributeError(name) 

雖然__init__是如下:

def __init__(self, string=None, **kwargs): 
     kwargs['string'] = string 
     args = {key: val for key, val in kwargs.iteritems() if val is not None} 
     self.args = args or EMPTY_DICT 
     self.setup_full_done = False 

在V8中fields.py __init__定義如下:

def __init__(self, string=None, **kwargs): 
     kwargs['string'] = string 
     attrs = {key: val for key, val in kwargs.iteritems() if val is not None} 
     self._attrs = attrs or EMPTY_DICT 

錯誤是:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in initialze 
    File "<stdin>", line 2, in add_a_field 
    File "openerp/fields.py", line 343, in __getattr__ 
    return self._attrs[name] 
    File "openerp/fields.py", line 343, in __getattr__ 
    return self._attrs[name] 
    File "openerp/fields.py", line 343, in __getattr__ 
    return self._attrs[name] 
    File "openerp/fields.py", line 343, in __getattr__ 
    return self._attrs[name] 
    File "openerp/fields.py", line 343, in __getattr__ 
    return self._attrs[name] 
: 
: 
: 
: 
RuntimeError: maximum recursion depth exceeded while calling a Python object 

任何想法,這個應該怎麼解決?

回答

1

一些經過調試和fields.py環顧四周,它得到了明顯的Odoo不再需要的模塊/應用程序代碼訪問使用點符號,因此,使用field.string訪問字段或字段的名稱初始化參數初始化又名參數。需要了解該字段是否是必需的,不再是有效的代碼片段。現在應該從一個名爲args的字典類型字段實例變量中訪問所有的初始化參數。

當我正在訪問字段。串在下面的代碼中,運行時錯誤被顯示出來:

def add_a_field(cls, field): 
    setattr(cls, field.string, field) 
    pass 

我現在已經修改了代碼如下:

def add_a_field(cls, field): 
    setattr(cls, field.args['string'], field) 
    pass 

指定參數和_attrs被定義爲在fields.py如下:

_slots = { 
    'args': EMPTY_DICT,    # the parameters given to __init__() 
    '_attrs': EMPTY_DICT,   # the field's non-slot attributes 

而之前在Odoo v8沒有參數,而_attrs的定義如下:

_slots = { 
    '_attrs': EMPTY_DICT,   # dictionary of field attributes; it contains: 
            # - all attributes after __init__() 
            # - free attributes only after set_class_name() 

所以在最後的模塊/應用程序代碼現在應該使用field.args [「字串」]或field.args [「所需」]代替點標記直接即field.string或field.required

相關問題