openerp经典收藏 对象定义详解(转载)
對象定義詳解
原文地址:
http://shine-it.net/index.php/topic,2159.0.html
http://blog.sina.com.cn/s/blog_57ded94e01013xa9.html
本連載準備詳細解密OpenERP的對象定義,內容包括深入理解OpenERP的對象,對象詳細定義、字段詳細定義、對象的預定義方法、OpenERP的Services等部分,力求每一部分都詳細說明。
要完全理解OpenERP的開發,需要理解這么幾個部分:OpenERP的對象,OpenERP的視圖及Action,OpenERP的Workflow,OpenERP的Report。理解了這幾部分就可以比較徹底的理解OpenERP開發平臺了,本連載力求解說第一部分。
本連載將會是OpenERP對象開發的“史上最牛”手冊,本連載的內容綜合了OpenERP的官方手冊,以及大量的“民間野史”,再加以大量的代碼研究和親自實驗,終熬制成本手冊。
本連載可算做OpenERP開發的提高篇,希望讀者對象先學習完《OpenERP應用和開發基礎》,參見http://shine-it.net/index.php/topic,882.0.html
第一部分:深入理解OpenERP的對象
由于寫作順序的緣故,放到后面去了,參見后面跟帖。
第二部分:OpenERP對象定義的屬性詳細解說
? ? OpenERP的對象定義的一般形式如下。
對象定義的完整屬性如下:
必須屬性
? ? ? ?_name? ? ?
? ? ? ?_columns??
可選屬性
? ? ? ?_table??
? ? ? ?_description
? ? ? ?_defaults
? ? ? ?_order
? ? ? ?_rec_name??
? ? ? ?_auto??
? ? ? ?_constraints
? ? ? ?_sql_constraints
? ? ? ?_inherit
? ? ? ?_inherits
下面詳細解說各個屬性。
_auto: 是否自動創建對象對應的Table,缺省值為: True。當安裝或升級模塊時,OpenERP會自動在數據庫中為模塊中定義的每個對象創建相應的Table。當這個屬性設為False時,OpenERP不會自動創建Table,這通常表示數據庫表已經存在。例如,當對象是從數據庫視圖(View)中讀取數據時,通常設為False。
_columns: 定義對象的字段,系統會字段為這里定義的每個字段在數據庫表中創建相應的字段。關于字段(Fields)的定義,參見后文。
_constraints: 定義于對象上的約束(constraints),通常是定義一個檢查函數,關于約束的詳細說明,參見后文。
_defaults: 定義字段的缺省值。當創建一條新記錄(record or resource)時,記錄中各字段的缺省值在此定義。
_description: 對象說明性文字,任意文字。
_log_access: 是否自動在對應的數據表中增加create_uid, create_date, write_uid, write_date四個字段,缺省值為True,即字段增加。這四個字段分布記錄record的創建人,創建日期,修改人,修改日期。這四個字段值可以用對象的方法(perm_read)讀取。
_name: 對象的唯一標識符,必須是全局唯一。這個標識符用于存取對象,其格式通常是"ModuleName.ClassName",對應的,系統會字段創建數據庫表"ModuleName_ClassName"。
_order: 定義search()和read()方法的結果記錄的排序規則,和SQL語句中的order 類似,缺省值是id,即按id升序排序。詳細說明參見后文。
_rec_name: 標識record name的字段。缺省情況(name_get沒被重載的話)方法name_get()返回本字段值。_rec_name通常用于記錄的顯示,例如,銷售訂單中包含業務伙伴,當在銷售訂單上顯示業務伙伴時,系統缺省的是顯示業務伙伴記錄的_rec_name。
_sequence: 數據庫表的id字段的序列采集器,缺省值為: None。OpenERP創建數據庫表時,會自動增加id字段作為主鍵,并自動為該表創建一個序列(名字通常是“表名_id_seq”)作為id字段值的采集器。如果想使用數據庫中已有的序列器,則在此處定義序列器名。
_sql: _auto為True時,可以在這里定義創建數據庫表的SQL語句。不過5.0以后好像不支持了,不建議使用。
_sql_constraints: 定義于對象上的約束(constraints),和SQL文中的約束類似,關于約束的詳細說明,參見后文。
_table: 待創建的數據庫表名,缺省值是和_name一樣,只是將"."替換成"_"。
_inherits:?
_inherit: _inherits和_inherit都用于對象的繼承,詳細說明參見后文。
_constraints
? ? _constraints可以靈活定義OpenERP對象的約束條件,當創建或更新記錄時,會觸發該條件,如果條件不符合,則彈出錯誤信息,拒絕修改。
? ? _constraints的定義格式:
? ? [(method, 'error message', list_of_field_names), ...]
· method: 是對象的方法,該方法的格式為:def _name_of_the_method(self, cr, uid, ids): ?> True|False
· error message: 不符合檢查條件(method返回False)時的錯誤信息。
· list_of_field_names: 字段名列表,這些字段的值會出現在error message中。通常列出能幫助用戶理解錯誤的字段。
??_constraints的例子:
? ? _sql_constraints定義數據表的約束條件,其格式如下例所示。
? ? _sql_constraints = [
? ? ? ? ('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
? ? ]
? ? 本例的_sql_constraints會在數據表中增加下述約束:
? ? CONSTRAINT ObjectName_code_company_uniq UNIQUE(code, company_id)
? ? _order在對象的search或read方法中的select語句上加上"Order"子句,如 _order = 'name desc, account_id',對應SQL文的Order子句:order by name desc, account_id。
_defaults
? ? _defaults屬性用于定義字段的缺省值,其格式為:
_defaults:
? ? {
? ? ? ? 'name_of_the_field':function, ...
? ? }
function的返回值作為'name_of_the_field'字段的缺省值。function格式是:function(obj, cr, uid, context),返回值必須是簡單類型,如boolean, integer, string 等。下面是_defaults的例子。
_defaults = {
? ? 'date_order': lambda *a: time.strftime('%Y?%m?%d'),
? ? 'state': lambda *a: 'draft',
? ? 'user_id': lambda obj, cr, uid, context: uid
}
lambda是Python的行函數,"lambda obj, cr, uid, context: uid"等同于下述函數:
def func(obj, cr, uid, context):
? ? return uid
_inherit和_inherits
? ? _inherit繼承有兩種情況,1)如果子類中不定義_name屬性,則相當于在父類中增加一些字段和方法,并不創建新對象。2)如果子類中定義_name屬性,則創建一個新對象,新對象擁有老對象的所有字段和方法,老對象不受任何影響。兩種情況的示例及繼承關系的圖示見下面。 ???
? ?class res_partner_add_langs(osv.osv):
???? ? _inherit = 'res.partner'
???? ? _columns = {
???? ? ? ? 'lang_ids' : fields.many2many('res.lang', 'res_lang_partner_rel', 'partner_id', 'lang_id', 'Languages'),
???? ? }
???res_partner_add_langs()
? ?class formateur(osv.osv):
???? ? _name = 'formateur'
???? ? _inherit = 'res.partner'
???? ? _columns = {
???? ? ? ? 'lang_ids' : fields.many2many('res.lang', 'res_lang_partner_rel', 'partner_id', 'lang_id', 'Languages'),
???? ? }
???formateur()
? ? _inherits相當于多重繼承。子類通過_inherits中定義的字段和各個父類關聯,子類不擁有父類的字段,但可以直接操作父類的所有字段和方法。_inherits的示例及圖示見下圖。
??
? ?class cursus_category(osv.osv):
???? ? _name = 'cursus.category'
???? ? _inherits = {'account.analytic.caccount':'analytic_caccount_id'}
???? ? _columns = {
???? ? ? ? 'analytic_caccount_id' : fields.many2one('account.analytic.caccount', 'ID'),
???? ? }
???cursus_category()
----------------------------------------------------------------------------------------------------------------------------------
"為人性僻耽佳句,語不驚人死不休"。老肖的文字不是用來驚人的,但是技術文檔能寫得如此透徹,絕對是花了功夫去專研理解的,向老肖致敬。
? 對文檔做一些小補充:
- _auto? ?當_auto的值為“False"時,OE不會自動在數據庫中創建相應的表,開發者可以在對應類的init()方法中定義表或視圖的SQL。這一般應用在? 報表所對應的數據對象中,因為報表的數據對象往往是“視圖”,所以我們可以在init()方法中創建所需的數據庫視圖SQL即可。
- _columns?OE并不一定為每個定義項創建數據庫字段,比如:selection, reference, one2many, function等字段是不會有對應的數據庫字段的。
- _name?當使用_inherit時可以與被繼承的類的_name一致,_name一致表示不創建新的數據庫表,而直接在原表上修改
- _rec_name? ?缺省的情況下,name_get方法使用表中的‘name'字段,所以當你定義了一個實體類B,并且實體類B中即沒有“name“字段也沒有為? _rec_name特別指定一個字段,? ?那么當OE調用name_get方法時(比如實體類A有一個many2one字段b指向實體類B,顯示A.b的值時就會調用類B的name_get方法)? 就會報“未定義name字段“的錯誤
- _inherits? ?另外還可以這樣理解_inherits,_inherits又被稱為實例繼承,就是新繼承的數據對象不但繼承被繼承對象的屬性和方法同時也繼承了數據實? 例,即表中的記錄。比如product類不但繼承product_template的屬性和方法,而且這兩個表的數據也是同步的。
- _defaults?在V6中字典的值可以不是函數,就比如在V5中我們必須這樣來定義:_defaults= { 'state' : lambda *a: 'draft'} 而在 V6中可以這樣來:_defaults = {'state' : 'draft'}
轉載于:https://www.cnblogs.com/cnshen/p/3166796.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的openerp经典收藏 对象定义详解(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过gdb调试分析Linux内核的启动过
- 下一篇: 为了IT人的荣耀,请大力支持《中国人的紧