Odoo ORM API(六)- Inheritance and extension and Domains

Inheritance and extension

Odoo 提供了三種不同機制用來擴展models in a modular way:

  • 繼承一個已經存在的model,添加一些新的屬性或者方法,但是,源model不會增加屬性或方法,只是自己改變
  • 在另外一個 Odoo module 中,直接擴展源model,給他添加新的屬性或方法,而不用去修改源碼
  • delegating some of the model’s fields to records it contains

這裏寫圖片描述

Classical inheritance

當同時使用_inhert_name 屬性時,Odoo 將根據 _inherit 創建一個名爲 _name 的新的model,這個新的 model 將從_inherit 的 model 中獲取所有的 fields,methods,meta-information。

class Inheritance0(models.Model):
    _name = 'inheritance.0'

    name = fields.Char()

    def call(self):
        return self.check("model 0")

    def check(self, s):
        return "This is {} record {}".format(s, self.name)

class Inheritance1(models.Model):
    _name = 'inheritance.1'
    _inherit = 'inheritance.0'

    def call(self):
        return self.check("model 1")

你這樣調用

        a = env['inheritance.0'].create({'name': 'A'})
        a.call()
        b = env['inheritance.1'].create({'name': 'B'})
        b.call()

產生下述結果

        This is model 0 record A
        This is model 1 record B

第二個 model 繼承了第一個 model 的 name field 和 check method,但是覆蓋了它的 call method,這種繼承方式和普通的 Python 繼承一樣。

Extension

當只設置了_inherit,沒有設置_name 屬性時,這個新的 model 就是直接對源 model 進行了擴展。這種機制通常是在其他 module 中對已有 module 中的model進行添加字段或方法,或者重新定製化他們(如:改變他們的默認 search order)

class Extension0(models.Model):
    _name = 'extension.0'

    name = fields.Char(default="A")

class Extension1(models.Model):
    _inherit = 'extension.0'

    description = fields.Char(default="Extended")
        record = env['extension.0'].create({})
        record.read()[0]

將產生

        {'name': "A", 'description': "Extended"}

當然,也會返回一些 自動建立的字段值,’create_uid’ 之類的

Delegation

第三種機制就更加的靈活了,使用_inherits 屬性,using the _inherits a model delegates the lookup of any field not found on the current model to “children” models. The delegation is performed via Reference fields automatically set up on the parent model:

class Child0(models.Model):
    _name = 'delegation.child0'

    field_0 = fields.Integer()

class Child1(models.Model):
    _name = 'delegation.child1'

    field_1 = fields.Integer()

class Delegating(models.Model):
    _name = 'delegation.parent'

    _inherits = {
        'delegation.child0': 'child0_id',
        'delegation.child1': 'child1_id',
    }

    child0_id = fields.Many2one('delegation.child0', required=True, ondelete='cascade')
    child1_id = fields.Many2one('delegation.child1', required=True, ondelete='cascade')
        record = env['delegation.parent'].create({
            'child0_id': env['delegation.child0'].create({'field_0': 0}).id,
            'child1_id': env['delegation.child1'].create({'field_1': 1}).id,
        })
        record.field_0
        record.field_1

f返回

        0
        1

可以直接對託管的字段進行修改:

        record.write({'field_1': 4})

使用這種機制,只有 field 會被繼承,method 不會。

Domains

一個 domain 就是一些條件組成的 list,每一個條件都是由3個元素組成,(field_name, operator, value

  • field_name (str)
    當前model 的一個 field name,或者是 Many2one field 組成 dot 鏈。如:'street''partner_id.country'
  • operator(str) 用來比較 field_namevalue,有:
    • =
    • !=
    • >
    • >=
    • <
    • <=
    • =? 這個字段如果有值,就用=比較;如果這個字段值爲 False 或者 None,返回 True
    • =like 這個字段是否滿足 value pattern,在 pattern 中 _ 代表 一個任意字符,%代表0或多個任意字符。
    • like pattern 直接就是 %value%
    • not like
    • ilike 不區分大小寫的 like
    • not ilike
    • =ilike 不區分大小寫的 =like
    • in value should be a list of items
    • not in
    • child_of
  • value variable type, must be comparable (through operator) to the named field

Domain 中的條件可以通過下面的邏輯運算符鏈接起來:

  • & 邏輯 AND, 兩個參數,將會默認的鏈接相鄰的兩個條件
  • | 邏輯 OR, 兩個參數
  • ! 邏輯 NOT,一個參數
    注意:表示否定的時候,儘量在條件中的 operator 表示,這樣比在外面表示更加的清晰明瞭。
[('name','=','ABC'),
 ('language.code','!=','en_US'),
 '|',('country_id.code','=','be'),
     ('country_id.code','=','de')]

這個翻譯過來就是

    (name is 'ABC')
AND (language is NOT english)
AND (country is Belgium OR Germany)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章