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的对象定义的一般形式如下。
class name_of_the_object(osv.osv):
_name = 'xxx'
......
name_of_the_object() #Sample:
class qingjd(osv.osv):
_name = 'qingjia.qingjd'
_description = '请假单'
_columns = {
'shenqr': fields.many2one('hr.employee', '申请人', required=True),
}
qingjd()
对象定义的完整属性如下:
必须属性
_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的例子:
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定义数据表的约束条件,其格式如下例所示。
_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'}
openerp经典收藏 对象定义详解(转载)的更多相关文章
- openerp经典收藏 字段定义详解(转载)
字段定义详解 原文地址:http://shine-it.net/index.php/topic,2159.0.htmlhttp://blog.sina.com.cn/s/blog_57ded94e01 ...
- openerp经典收藏 对象的预定义方法(转载)
对象的预定义方法 原文:http://shine-it.net/index.php/topic,2159.15.html 每个OpenERP的对象都有一些预定义方法,这些方法定义在基类osv.osv中 ...
- jQuery的deferred对象详解(转载)
本文转载自: jQuery的deferred对象详解(转载)
- 【转载】C++宏定义详解
摘自:http://blog.chinaunix.net/uid-21372424-id-119797.html C++宏定义详解 2011-02-14 23:33:24 分类: C/C++ ...
- Java 反射 设计模式 动态代理机制详解 [ 转载 ]
Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...
- 如约而至,Java 10 正式发布! Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势 努力的孩子运气不会太差,跌宕的人生定当更加精彩 优先队列详解(转载)
如约而至,Java 10 正式发布! 3 月 20 日,Oracle 宣布 Java 10 正式发布. 官方已提供下载:http://www.oracle.com/technetwork/java ...
- malloc 与 free函数详解<转载>
malloc和free函数详解 本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...
- javascript event(事件对象)详解
javascript event(事件对象)详解 1. 事件对象 1. 事件对象 Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 什 ...
- GridView内容详解(转载)
GridView内容详解(转载) GridView是ASP.NET界面开发中的一个重要的控件,对GridView使用的熟练程度直接影响软件开发的进度及功能的实现.(车延禄)GridView的主要新特性 ...
随机推荐
- 1. RAID在数据库存储上的应用
随着单块磁盘在数据安全.性能.容量上呈现出的局限,磁盘阵列(Redundant Arrays of Inexpensive/Independent Disks,RAID)出现了,RAID把多块独立的磁 ...
- JSP起源、JSP的运行原理、JSP的执行过程
JSP起源 在很多动态网页中,绝大部分内容都是固定不变的,只有局部内容需要动态产生和改变. 如果使用Servlet程序来输出只有局部内容需要动态改变的网页,其中所有的静态内容也需要程序员用Java程序 ...
- Shell学习笔记 - Shell变量
一.变量的命名 变量名必须以字母或下划线开头,由字母.数字.或下划线组成,变量名的长度不能超过255个字符. 二.变量的分类 1. 用户自定义变量 2. 环境变量 3. 位置参数变量 4. 预定义变量 ...
- codeforces 676A A. Nicholas and Permutation(水题)
题目链接: A. Nicholas and Permutation time limit per test 1 second memory limit per test 256 megabytes i ...
- 1027 姓名与ID[二分图匹配(匈牙利)]
1027 姓名与ID 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 有N个人,各自有一 ...
- 【转】华为Java编程军规,每季度代码验收标准
引言: 这个标准是衡量代码本身的缺陷,也是衡量一个研发人员本身的价值. 军规一:[避免在程序中使用魔鬼数字,必须用有意义的常量来标识.] 军规二:[明确方法的功能,一个方法仅完成一个功能.] 军规三: ...
- 基础面试题——HTML/CSS
1. 常用那几种浏览器测试?有哪些内核(Layout Engine)? (Q1)浏览器:IE,Chrome,FireFox,Safari,Opera. (Q2)内核:Trident,Gecko,Pre ...
- Java类加载的时机_4种主动引用会触犯类加载+剩下的被动引用不会触发类的加载
转载自:http://chenzhou123520.iteye.com/blog/1597597 Java虚拟机规范没有强制性约束在什么时候开始类加载过程,但是对于初始化阶段,虚拟机规范则严格规定了有 ...
- mysql一对多关联查询的时候筛选条件
mysql实现users 表和 logoin_log表是一对多, 现在是把user的信息找出来 关联上一些 logoin_log表的数据, 因为a表是多的一方,要多他的数据进行一些条件匹配,这个sql ...
- spring3+struts2+hibernate3整合出现的问题,No mapping found for dependency [type=java.lang.String, name='struts.objectFactory.spring.enableAopSupport']
七月 11, 2016 3:49:24 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetPropertiesRule ...