openerp经典收藏 对象定义详解(转载)
對(duì)象定義詳解
原文地址:
http://shine-it.net/index.php/topic,2159.0.html
http://blog.sina.com.cn/s/blog_57ded94e01013xa9.html
本連載準(zhǔn)備詳細(xì)解密OpenERP的對(duì)象定義,內(nèi)容包括深入理解OpenERP的對(duì)象,對(duì)象詳細(xì)定義、字段詳細(xì)定義、對(duì)象的預(yù)定義方法、OpenERP的Services等部分,力求每一部分都詳細(xì)說(shuō)明。
要完全理解OpenERP的開(kāi)發(fā),需要理解這么幾個(gè)部分:OpenERP的對(duì)象,OpenERP的視圖及Action,OpenERP的Workflow,OpenERP的Report。理解了這幾部分就可以比較徹底的理解OpenERP開(kāi)發(fā)平臺(tái)了,本連載力求解說(shuō)第一部分。
本連載將會(huì)是OpenERP對(duì)象開(kāi)發(fā)的“史上最牛”手冊(cè),本連載的內(nèi)容綜合了OpenERP的官方手冊(cè),以及大量的“民間野史”,再加以大量的代碼研究和親自實(shí)驗(yàn),終熬制成本手冊(cè)。
本連載可算做OpenERP開(kāi)發(fā)的提高篇,希望讀者對(duì)象先學(xué)習(xí)完《OpenERP應(yīng)用和開(kāi)發(fā)基礎(chǔ)》,參見(jiàn)http://shine-it.net/index.php/topic,882.0.html
第一部分:深入理解OpenERP的對(duì)象
由于寫(xiě)作順序的緣故,放到后面去了,參見(jiàn)后面跟帖。
第二部分:OpenERP對(duì)象定義的屬性詳細(xì)解說(shuō)
OpenERP的對(duì)象定義的一般形式如下。
class name_of_the_object(osv.osv):
_name = 'xxx'
......
name_of_the_object()
#Sample:
class qingjd(osv.osv):
_name = 'qingjia.qingjd'
_description = '請(qǐng)假單'
_columns = {
'shenqr': fields.many2one('hr.employee', '申請(qǐng)人', required=True),
}
qingjd()
對(duì)象定義的完整屬性如下:
必須屬性
_name
_columns
可選屬性
_table
_description
_defaults
_order
_rec_name
_auto
_constraints
_sql_constraints
_inherit
_inherits
下面詳細(xì)解說(shuō)各個(gè)屬性。
_auto: 是否自動(dòng)創(chuàng)建對(duì)象對(duì)應(yīng)的Table,缺省值為: True。當(dāng)安裝或升級(jí)模塊時(shí),OpenERP會(huì)自動(dòng)在數(shù)據(jù)庫(kù)中為模塊中定義的每個(gè)對(duì)象創(chuàng)建相應(yīng)的Table。當(dāng)這個(gè)屬性設(shè)為False時(shí),OpenERP不會(huì)自動(dòng)創(chuàng)建Table,這通常表示數(shù)據(jù)庫(kù)表已經(jīng)存在。例如,當(dāng)對(duì)象是從數(shù)據(jù)庫(kù)視圖(View)中讀取數(shù)據(jù)時(shí),通常設(shè)為False。
_columns: 定義對(duì)象的字段,系統(tǒng)會(huì)字段為這里定義的每個(gè)字段在數(shù)據(jù)庫(kù)表中創(chuàng)建相應(yīng)的字段。關(guān)于字段(Fields)的定義,參見(jiàn)后文。
_constraints: 定義于對(duì)象上的約束(constraints),通常是定義一個(gè)檢查函數(shù),關(guān)于約束的詳細(xì)說(shuō)明,參見(jiàn)后文。
_defaults: 定義字段的缺省值。當(dāng)創(chuàng)建一條新記錄(record or resource)時(shí),記錄中各字段的缺省值在此定義。
_description: 對(duì)象說(shuō)明性文字,任意文字。
_log_access: 是否自動(dòng)在對(duì)應(yīng)的數(shù)據(jù)表中增加create_uid, create_date, write_uid, write_date四個(gè)字段,缺省值為T(mén)rue,即字段增加。這四個(gè)字段分布記錄record的創(chuàng)建人,創(chuàng)建日期,修改人,修改日期。這四個(gè)字段值可以用對(duì)象的方法(perm_read)讀取。
_name: 對(duì)象的唯一標(biāo)識(shí)符,必須是全局唯一。這個(gè)標(biāo)識(shí)符用于存取對(duì)象,其格式通常是"ModuleName.ClassName",對(duì)應(yīng)的,系統(tǒng)會(huì)字段創(chuàng)建數(shù)據(jù)庫(kù)表"ModuleName_ClassName"。
_order: 定義search()和read()方法的結(jié)果記錄的排序規(guī)則,和SQL語(yǔ)句中的order 類(lèi)似,缺省值是id,即按id升序排序。詳細(xì)說(shuō)明參見(jiàn)后文。
_rec_name: 標(biāo)識(shí)record name的字段。缺省情況(name_get沒(méi)被重載的話)方法name_get()返回本字段值。_rec_name通常用于記錄的顯示,例如,銷(xiāo)售訂單中包含業(yè)務(wù)伙伴,當(dāng)在銷(xiāo)售訂單上顯示業(yè)務(wù)伙伴時(shí),系統(tǒng)缺省的是顯示業(yè)務(wù)伙伴記錄的_rec_name。
_sequence: 數(shù)據(jù)庫(kù)表的id字段的序列采集器,缺省值為: None。OpenERP創(chuàng)建數(shù)據(jù)庫(kù)表時(shí),會(huì)自動(dòng)增加id字段作為主鍵,并自動(dòng)為該表創(chuàng)建一個(gè)序列(名字通常是“表名_id_seq”)作為id字段值的采集器。如果想使用數(shù)據(jù)庫(kù)中已有的序列器,則在此處定義序列器名。
_sql: _auto為T(mén)rue時(shí),可以在這里定義創(chuàng)建數(shù)據(jù)庫(kù)表的SQL語(yǔ)句。不過(guò)5.0以后好像不支持了,不建議使用。
_sql_constraints: 定義于對(duì)象上的約束(constraints),和SQL文中的約束類(lèi)似,關(guān)于約束的詳細(xì)說(shuō)明,參見(jiàn)后文。
_table: 待創(chuàng)建的數(shù)據(jù)庫(kù)表名,缺省值是和_name一樣,只是將"."替換成"_"。
_inherits:
_inherit: _inherits和_inherit都用于對(duì)象的繼承,詳細(xì)說(shuō)明參見(jiàn)后文。
_constraints
_constraints可以靈活定義OpenERP對(duì)象的約束條件,當(dāng)創(chuàng)建或更新記錄時(shí),會(huì)觸發(fā)該條件,如果條件不符合,則彈出錯(cuò)誤信息,拒絕修改。
_constraints的定義格式:
[(method, 'error message', list_of_field_names), ...]
· method: 是對(duì)象的方法,該方法的格式為:def _name_of_the_method(self, cr, uid, ids): ?> True|False
· error message: 不符合檢查條件(method返回False)時(shí)的錯(cuò)誤信息。
· list_of_field_names: 字段名列表,這些字段的值會(huì)出現(xiàn)在error message中。通常列出能幫助用戶理解錯(cuò)誤的字段。
_constraints的例子:
def _constraint_sum(self, cr, uid, ids):
cr.execute('SELECT a.currency_id
FROM account_move m, account_move_line l, account_account a
WHERE m.id=l.move_id AND l.account_id=a.id AND m.id IN ('+','.join(map(str, ids))+')
GROUP BY a.currency_id')
if len(cr.fetchall()) >= 2:
return True
cr.execute('SELECT abs(SUM(l.amount))
FROM account_move m LEFT JOIN account_move_line l ON (m.id=l.move_id)
WHERE m.id IN ('+','.join(map(str, ids))+')')
res = cr.fetchone()[0]
return res < 0.01
_constraints = [
(_constraint_sum, 'Error: the sum of all amounts should be zero.', ['name'])
]
_sql_constraints 和 _order
_sql_constraints定義數(shù)據(jù)表的約束條件,其格式如下例所示。
_sql_constraints = [
('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
]
本例的_sql_constraints會(huì)在數(shù)據(jù)表中增加下述約束:
CONSTRAINT ObjectName_code_company_uniq UNIQUE(code, company_id)
_order在對(duì)象的search或read方法中的select語(yǔ)句上加上"Order"子句,如 _order = 'name desc, account_id',對(duì)應(yīng)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),返回值必須是簡(jiǎn)單類(lèi)型,如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的行函數(shù),"lambda obj, cr, uid, context: uid"等同于下述函數(shù):
def func(obj, cr, uid, context):
return uid
_inherit和_inherits
_inherit繼承有兩種情況,1)如果子類(lèi)中不定義_name屬性,則相當(dāng)于在父類(lèi)中增加一些字段和方法,并不創(chuàng)建新對(duì)象。2)如果子類(lèi)中定義_name屬性,則創(chuàng)建一個(gè)新對(duì)象,新對(duì)象擁有老對(duì)象的所有字段和方法,老對(duì)象不受任何影響。兩種情況的示例及繼承關(guān)系的圖示見(jiàn)下面。
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相當(dāng)于多重繼承。子類(lèi)通過(guò)_inherits中定義的字段和各個(gè)父類(lèi)關(guān)聯(lián),子類(lèi)不擁有父類(lèi)的字段,但可以直接操作父類(lèi)的所有字段和方法。_inherits的示例及圖示見(jiàn)下圖。
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()
----------------------------------------------------------------------------------------------------------------------------------
"為人性僻耽佳句,語(yǔ)不驚人死不休"。老肖的文字不是用來(lái)驚人的,但是技術(shù)文檔能寫(xiě)得如此透徹,絕對(duì)是花了功夫去專(zhuān)研理解的,向老肖致敬。
對(duì)文檔做一些小補(bǔ)充:
_auto 當(dāng)_auto的值為“False"時(shí),OE不會(huì)自動(dòng)在數(shù)據(jù)庫(kù)中創(chuàng)建相應(yīng)的表,開(kāi)發(fā)者可以在對(duì)應(yīng)類(lèi)的init()方法中定義表或視圖的SQL。這一般應(yīng)用在 報(bào)表所對(duì)應(yīng)的數(shù)據(jù)對(duì)象中,因?yàn)閳?bào)表的數(shù)據(jù)對(duì)象往往是“視圖”,所以我們可以在init()方法中創(chuàng)建所需的數(shù)據(jù)庫(kù)視圖SQL即可。
_columnsOE并不一定為每個(gè)定義項(xiàng)創(chuàng)建數(shù)據(jù)庫(kù)字段,比如:selection, reference, one2many, function等字段是不會(huì)有對(duì)應(yīng)的數(shù)據(jù)庫(kù)字段的。
_name當(dāng)使用_inherit時(shí)可以與被繼承的類(lèi)的_name一致,_name一致表示不創(chuàng)建新的數(shù)據(jù)庫(kù)表,而直接在原表上修改
_rec_name 缺省的情況下,name_get方法使用表中的‘name'字段,所以當(dāng)你定義了一個(gè)實(shí)體類(lèi)B,并且實(shí)體類(lèi)B中即沒(méi)有“name“字段也沒(méi)有為 _rec_name特別指定一個(gè)字段, 那么當(dāng)OE調(diào)用name_get方法時(shí)(比如實(shí)體類(lèi)A有一個(gè)many2one字段b指向?qū)嶓w類(lèi)B,顯示A.b的值時(shí)就會(huì)調(diào)用類(lèi)B的name_get方法) 就會(huì)報(bào)“未定義name字段“的錯(cuò)誤
_inherits 另外還可以這樣理解_inherits,_inherits又被稱為實(shí)例繼承,就是新繼承的數(shù)據(jù)對(duì)象不但繼承被繼承對(duì)象的屬性和方法同時(shí)也繼承了數(shù)據(jù)實(shí) 例,即表中的記錄。比如product類(lèi)不但繼承product_template的屬性和方法,而且這兩個(gè)表的數(shù)據(jù)也是同步的。
_defaults在V6中字典的值可以不是函數(shù),就比如在V5中我們必須這樣來(lái)定義:_defaults= { 'state' : lambda *a: 'draft'} 而在 V6中可以這樣來(lái):_defaults = {'state' : 'draft'}
總結(jié)
以上是生活随笔為你收集整理的openerp经典收藏 对象定义详解(转载)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C#使用Ado.net读取Excel表的
- 下一篇: 万维网联盟