Odoo ORM API(七)- Porting from the old API to the new API

Porting from the old API to the new API

  • 在 new API 中避免了直接使用 ids 組成的 list,而使用 recordsets
  • 使用 old API 方式寫的 method 將會被 ORM 自動的轉換,沒有必要切換到老的 pool 來調用 old API,可以直接把它當成 new API ,用 recordset 來調用
  • search() 直接返回一個 recordsets
  • fields.related and fields.function 都被替換成普通的field,只不過給它設置了 related= 或者 compute= 參數
  • computed= 設置的 method 必需設置depends(),必需將所有依賴的字段全部列出來,多列出來比少列出來要好,以免該 重新計算的時候沒有計算
  • 移除了所有computed fields 的 onchange method,computed fields 在他依賴的字段發生變化時,將會自動的重新計算,也會被clinet 自動的 onchange
  • 裝飾器 model()multi() 是爲了從 old API 調用它時,自動轉換。如果你的項目中全是 new API 的話,那麼這兩個裝飾器不會起作用
  • 移除 _default,該而在相關字段定義時,設置 default 參數。
  • 如果某個字段的 string= 參數就是 field name的首字母大寫,那麼你應該避免設置這個參數

    name = fields.Char(string="Name")
  • multi= 參數也不會在 new API 定義中生效,可以通過給相關 field 設置 compute= 同一個方法

  • compute= inverse= search= 的值都是作爲字符串傳遞的,這也方便複寫
  • 必需確保所有的 field name 和 method name 的名字沒有衝突,如果重名了,Odoo 將不會產生任何的警告,因爲在 Odoo 系統生效之前,Python 已經先行處理了。
  • 通常 new-api 中 import 就是 from openerp import fields, models,如果有必要使用裝飾器,使用from openerp import api, fields, models
  • 儘量不要使用 one() 裝飾器,它很有可能不會按照你預期的結果返回
  • 移除了顯示的定義create_uid, create_date, write_uid, write_date fields,他們現在像普通的fields一樣,可以被讀寫 out-of-the-box
  • when straight conversion is impossible (semantics can not be bridged) 或者 odl API 版本不太符合新的要求,在 new API 中改進了。你可以使用裝飾器v7() v8() 來裝飾同一名字的method,那麼當你從 old-style 的方式調用這個method,那麼將使用 v7裝飾的method, 如果你是以 recordset來調用這個 method,那麼將使用 v8 裝飾的method。One implementation can call (and frequently does) call the other by switching context.

    使用這兩個裝飾器,將會使得methods非常難的複寫,並且不宜被理解

  • _columns or _all_columns 應該用 _fields 替換,which provides access to instances of new-style openerp.fields.Field instances (rather than old-style openerp.osv.fields._column).
    Non-stored computed fields created using the new API style are not available in _columns and can only be inspected through _fields

  • 在 method 中重新定義 self 將是沒有必要的, may break translation introspection

  • Enviroment 對象通常依賴於一些 threadlocal state,通常在使用之前就被初始化定義好了。如果你在 env 沒有初始化的情況下,想通過new API context 做一些事情,你必需要使用openerp.api.Envrionment.manage()。比如是一個新的線程,或者python的交互模式中。

    >>> from openerp import api, modules
    >>> r = modules.registry.RegistryManager.get('test')
    >>> cr = r.cursor()
    >>> env = api.Environment(cr, 1, {})
    Traceback (most recent call last):
    ...
    AttributeError: environments
    >>> with api.Environment.manage():
    ...     env = api.Environment(cr, 1, {})
    ...     print env['res.partner'].browse(1)
    ...
    res.partner(1,)

Automatic bridging of old API methods

當初始化一個 model 的時候,這個 method 的方法將會被自動掃描,如果這個 model 是按照 old-api的方式被定義,那麼這些方法也會被自動的 bridged。這使得它們可以在 new-api style 中被調用。
如果 methods 的第二個位置參數(after self)是 cr 或者 cursor,那麼這個method 就 matched as “old-API style”,system 也能識別到第三個位置參數 being called uid or user ,第四個位置參數 id or ids,以及關鍵字參數context
當從 new API context 下面調用這些 符合上述要求的 methods,Odoo 將會自動的從當前Environment 帶入(cr, user, context),從 self 中 帶入 (id or ids)。
復非常少見,但是還是有必要說一下的,通過裝飾器,可以對 old-style method 自定義轉換:

  • 可以通過裝飾器 noguess() 來停止對這個 method 的自動 bridge。這樣你就必需按照定義的方式從 按照 新舊 API 方式分別調用
  • 自定義 bridge,通常是因爲有些 method 定義的不太準確(因爲 參數的命名不是按照期望的那樣):

    • cr()
      將會自動的在已設置的參數之前,添加一個 current cr
    • cr_uid()
      將會自動的在已設置的參數之前,添加一個 current cr, uid
    • cr_uid_ids()
      將會自動的在已設置的參數之前,添加一個 current cr, uid, ids
    • cr_uid_id()
      loop over the current recordset and call the method for each record,將會自動的在已設置的參數之前,添加一個 current cr, uid, id。這個裝飾器之後,即使從 new-api 調用也會返回 list,而不是recordset

    這幾個方法都可以在後面添加 _context(),用以傳入 關鍵字參數context。 如: cr_context(), cr_uid_context() 等

  • dual implementations using v7() and v8() will be ignored as they provide their own “bridging”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章