定义模型的时候,和python的其他框架类似,可以对比Django,同样是一个模型即:一个class对应生成数据库中的一张表,

只是odoo的继承机制比较复杂一点,在日常的开发中,定义模型的时候,

基本字段类型有:

Char、Text、Selection、Html、Integer、Float、Date、Datetime、Boolean、Binary。

复杂类型:selection, function, related

用于设置类似主外键关联关系的字段有:

Many2many

Many2one

One2many

下面逐一说明:

基本字段类型

boolean: 布尔型(true, false)
integer: 整数。
float: 浮点型,如 'rate' : fields.float('Relative Change rate',digits=(12,6)), digits定义整数部分和小数部分的位数。
char: 字符型,size属性定义字符串长度。
text: 文本型,没有长度限制。
date: 日期型
datetime: 日期时间型
binary: 二进制型

复杂类型

function: 函数型,该类型的字段,字段值由函数计算而得,不存储在数据表中。其定义格式为:
fields.function(fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='float', fnct_search=None, obj=None, method=False, store=True)
· type 是函数返回值的类型。
· method 为True表示本字段的函数是对象的一个方法,为False表示是全局函数,不是对象的方法。如果method=True,obj指定method的对象。
· fcnt 是函数或方法,用于计算字段值。如果method = true, 表示fcnt是对象的方法,其格式如下:def fnct(self, cr, uid, ids, field_name, args, context),否则,其格式如下:def fnct(cr, table, ids, field_name, args, context)。ids是系统传进来的当前存取的record id。field_name是本字段名,当一个函数用于多个函数字段类型时,本参数可区分字段。args是'arg=None'传进来的参数。
· fcnt_inv 是用于写本字段的函数或方法。如果method = true, 其格式是:def fcnt_inv(self, cr, uid, ids, field_name, field_value, args, context),否则格式为:def fcnt_inv(cr, table, ids, field_name, field_value, args, context)
· fcnt_search 定义该字段的搜索行为。如果method = true, 其格式为:def fcnt_search(self, cr, uid, obj, field_name, args),否则格式为:def fcnt_search(cr, uid, obj, field_name, args)
· store 表示是否希望在数据库中存储本字段值,缺省值为False。不过store还有一个增强形式,格式为 store={'object_name':(function_name,['field_name1','field_name2'],priority)} ,其含义是,如果对象'object_name'的字段['field_name1','field_name2']发生任何改变,系统将调用函数function_name,函数的返回结果将作为参数(arg)传送给本字段的主函数,即fnct。
selection: 下拉框字段。定义一个下拉框,允许用户选择值。如:'state': fields.selection((('n','Unconfirmed'),('c','Confirmed')),'State', required=True),这表示state字段有两个选项('n','Unconfirmed')和('c','Confirmed')。 related: 关联字段,表示本字段引用关联表中的某字段。格式为:fields.related(关系字段,引用字段,type, relation, string, ...),关系字段是本对象的某字段(通常是one2many or many2many),引用字段是通过关系字段关联的数据表的字段,type是引用字段的类型,如果type是many2one or many2many, relation指明关联表。例子如下:
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'),
'city':fields.related('address','city',type='char', string='City'),
'country':fields.related('address','country_id',type='many2one', relation='res.country', string='Country'),

这里,city引用address的city字段,country引用address的country对象。在address的关联对象res.partner.address中,country_id是many2one类型的字段,所以type='many2one', relation='res.country'。

关联关系的字段

one2one: 一对一关系,格式为:fields.one2one(关联对象Name, 字段显示名, ... )。在V5.0以后的版本中不建议使用,而是用many2one替代。odoo9.0之后不支持一对一该字段类型。
many2one: 多对一关系,格式为:fields.many2one(关联对象Name, 字段显示名, ... )。可选参数有:ondelete,可选值为"cascade"和"null",缺省值为"null",表示one端的record被删除后,many端的record是否级联删除。
one2many: 一对多关系,格式为:fields.one2many(关联对象Name, 关联字段, 字段显示名, ... ),例:'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts')。
many2many: 多对多关系。例如:
'category_id':fields.many2many('res.partner.category','res_partner_category_rel','partner_id','category_id','Categories'),
表示以多对多关系关联到对象res.partner.category,关联表为'res_partner_category_rel',关联字段为'partner_id'和'category_id'。当定义上述字段时,OpenERP会自动创建关联表为'res_partner_category_rel',它含有关联字段'partner_id'和'category_id'。

reference: 引用型,格式为:fields.reference(字段名, selection, size, ... )。其中selection是: 1)返回tuple列表的函数,或者 2)表征该字段引用哪个对象(or model)的tuples列表。reference字段在数据库表中的存储形式是(对象名,ID),如(product.product,3)表示引用对象product.product(数据表product_product)中id=3的数据。reference的例子:
    def _links_get(self, cr, uid):
        cr.execute('select object,name from res_request_link order by priority')
        return cr.fetchall()

...
    'ref':fields.reference('Document Ref 2', selection=_links_get, size=128),
    ...
上例表示,字段ref可以引用哪些对象类型的resource,可引用的对象类型从下拉框选择。下拉框的选项由函数_links_get返回,是(object,name)对的列表,如[("product.product","Product"), ("account.invoice","Invoice"), ("stock.production.lot","Production Lot")] 。

property: 属性字段,下面以具体例子解说property字段类型。
'property_product_pricelist': fields.property('product.pricelist', type='many2one', relation='product.pricelist',string="Sale Pricelist", method=True, view_load=True, group_name="Pricelists Properties")
这个例子表示,本对象通过字段'property_product_pricelist'多对一(type='many2one')关联到对象product.pricelist(relation='product.pricelist')。和many2one字段类型不同的是,many2one字段会在本对象中创建数据表字段'property_product_pricelist',property字段类型不会创建数据表字段'property_product_pricelist'。property字段类型会从数据表ir.property中查找name='property_product_pricelist'(即字段定义中的'product.pricelist'加上前缀property,并将"."替换成"_"作为name)且company_id和本对象相同的记录,从该记录的value字段(value字段类型为reference)查得关联记录,如(product.pricelist,1),表示本对象的resource多对一关联到对象product.pricelist的id=1的记录。也就是说,property字段类型通过ir.property间接多对一关联到别的对象。
    property字段类型基本上和many2one字段类型相同,但是有两种情况优于many2one字段。其一是,例如,当有多条记录通过ir.property的name='property_product_pricelist'的记录关联到记录(product.pricelist,1),此时,如果希望将所有关联关系都改成关联到记录(product.pricelist,2)。如果是many2one类型,不写代码,很难完成此任务,是property字段的话,只要将ir.property中的value值(product.pricelist,1)改成(product.pricelist,2),则所有关联关系都变了。修改ir.property的value值可以在系统管理下的菜单Configuration --> Properties中修改。其二是,例如,同一业务伙伴,但希望A公司的用户进来看到的该业务伙伴价格表为pricelistA,B公司的用户进来看到的该业务伙伴价格表为pricelistB,则many2one类型达不到该效果。property类型通过ir.property中的记录关联时加上了company_id的条件,因此可以使得不同公司的员工进来看到不同的关联记录。
    由于property类型通过ir.property关联,因此,每个property类型的字段都必须在ir.property中有一条关联记录。这可以在安装时导入该条记录,参考代码如下:
    <record model="ir.property" id="property_product_pricelist">
        <field name="name">property_product_pricelist</field>
        <field name="fields_id" search="[('model','=','res.partner'), ('name','=','property_product_pricelist')]"/>
        <field name="value" eval="'product.pricelist,'+str(list0)"/>
    </record>

字段定义的参数
    字段定义中可用的参数有, change_default,readonly,required,states,string,translate,size,priority,domain,invisible,context,selection。
change_default:别的字段的缺省值是否可依赖于本字段,缺省值为:False。例子(参见res.partner.address),
    'zip': fields.char('Zip', change_default=True, size=24),

这个例子中,可以根据zip的值设定其它字段的缺省值,例如,可以通过程序代码,如果zip为200000则city设为“上海”,如果zip为100000则city为“北京”。

readonly: 本字段是否只读,缺省值:False。
required: 本字段是否必须的,缺省值:False。
states: 定义特定state才生效的属性,格式为:{'name_of_the_state': list_of_attributes},其中list_of_attributes是形如[('name_of_attribute', value), ...]的tuples列表。例子(参见account.transfer):
    'partner_id': fields.many2one('res.partner', 'Partner', states={'posted':[('readonly',True)]}),

string: 字段显示名,任意字符串。
translate: 本字段值(不是字段的显示名)是否可翻译,缺省值:False。
size: 字段长度。
priority:
domain: 域条件,缺省值:[]。在many2many和many2one类型中,字段值是关联表的id,域条件用于过滤关联表的record。例子:
'default_credit_account_id': fields.many2one('account.account', 'Default Credit Account', domain="[('type','!=','view')]"),

本例表示,本字段关联到对象('account.account')中的,type不是'view'的record。

invisible: 本字段是否可见,即是否在界面上显示本字段,缺省值True。
selection: 只用于reference字段类型,参见前文reference的说明。

> 另外一个问题就是function的store=true有没有意义呢,不是每次读取这个function就会执行里面的方法,那么还储存在数据库里面有什么作用?
我的理解是store=true可以将每次函数计算的结果存储到数据库中,这样有两个好处,一是便于DBA从数据库查看数据;二是非OpenERP的软件可以直接访问数据库共享数据。另外补充一点,fcnt_inv不限于写入本对象的数据表,更经常的情形是写入别的对象,甚至同时写入多个对象的数据表。

> <field name="value" eval="'product.pricelist,'+str(list0)"/>
前文说过,value字段类型为reference,即形如(product.pricelist,1)的值。这一行就是计算value的值,形如(product.pricelist,list0),list0(经导入后其值是数字)是引用的product.pricelist中的一条记录的id,如下。
        <record id="list0" model="product.pricelist">
            <field name="name">Default Purchase Pricelist</field>
            <field name="type">purchase</field>
        </record>
也就是说,在<field name="value" eval="'product.pricelist,'+str(list0)"/>之前,必须先有上述导入id="list0"的代码行。
 每个OpenERP的对象都有一些预定义方法,这些方法定义在基类osv.osv中。这些预定义方法有:
基本方法:create, search, read, browse, write, unlink。
    def create(self, cr, uid, vals, context={})
    def search(self, cr, uid, args, offset=0, limit=2000)
   def read(self, cr, uid, ids, fields=None, context={})
   def browse(self, cr, uid, select, offset=0, limit=2000)
   def write(self, cr, uid, ids, vals, context={})
   def unlink(self, cr, uid, ids)

缺省值存取方法:default_get, default_set。
def default_get(self, cr, uid, fields, form=None, reference=None)
def default_set(self, cr, uid, field, value, for_user=False)

特殊字段操作方法:perm_read, perm_write
def perm_read(self, cr, uid, ids)
def perm_write(self, cr, uid, ids, fields)

字段(fields)和视图(views)操作方法:fields_get, distinct_field_get, fields_view_get
def fields_get(self, cr, uid, fields = None, context={})
def fields_view_get(self, cr, uid, view_id=None, view_type='form',context={})
def distinct_field_get(self, cr, uid, field, value, args=[], offset=0,limit=2000)

记录名字存取方法:name_get, name_search
def name_get(self, cr, uid, ids, context={})
def name_search(self, cr, uid, name='', args=[], operator='ilike',context={})

缺省值存取方法:default_get, default_set
def name_get(self, cr, uid, ids, context={})
def name_search(self, cr, uid, name=, args=[], operator=’ilike’, context={})

create方法:在数据表中插入一条记录(或曰新建一个对象的resource)。
格式:def create(self, cr, uid, vals, context={})
参数说明:
vals: 待新建记录的字段值,是一个字典,形如: {'name_of_the_field':value, ...}
context (optional): OpenERP几乎所有的方法都带有参数context,context是一个字典,存放一些上下文值,例如当前用户的信息,包括语言、角色等。context可以塞入任何值,在action定义中,有一个context属性,在界面定义时,可以在该属性中放入任何值,context的最初值通常来自该属性值。
返回值:新建记录的id。
举例:id = pooler.get_pool(cr.dbname).get('res.partner.event').create(cr, uid,{'name': 'Email sent through mass mailing','partner_id': partner.id,'description': 'The Description for Partner Event'})

search方法:查询符合条件的记录。
格式:def search(self, cr, uid, args, offset=0, limit=2000)
参数说明:
args: 包含检索条件的tuples列表,格式为: [('name_of_the_field', 'operator', value), ...]。可用的operators有:
  =, >, <, <=, >=
  in
  like, ilike
  child_of
更详细说明,参考《OpenERP应用和开发基础》中的“域条件”有关章节。

· offset (optional): 偏移记录数,表示不返回检索结果的前offset条。
· limit (optional): 返回结果的最大记录数。
返回值:符合条件的记录的id list。

read方法:返回记录的指定字段值列表。
格式:def read(self, cr, uid, ids, fields=None, context={})
参数说明:
· ids: 待读取的记录的id列表,形如[1,3,5,...]
· fields (optionnal): 待读取的字段值,不指定的话,读取所有字段。
· context (optional): 参见create方法。
返回值:返回读取结果的字典列表,形如 [{'name_of_the_field': value, ...}, ...]

browse方法:浏览对象及其关联对象。从数据库中读取指定的记录,并生成对象返回。和read等方法不同,本方法不是返回简单的记录,而是返回对象。返回的对象可以直接使用"."存取对象的字段和方法,形如"object.name_of_the_field",关联字段(many2one等),也可以通过关联字段直接访问“相邻”对象。例如:
    addr_obj = self.pool.get('res.partner.address').browse(cr, uid, contact_id)
    nom = addr_obj.name
    compte = addr_obj.partner_id.bank
这段代码先从对象池中取得对象res.partner.address,调用它的方法browse,取得id=contact_id的对象,然后直接用"."取得"name"字段以及关联对象patner的银行(addr_obj.partner_id.bank)。

格式:def browse(self, cr, uid, select, offset=0, limit=2000)
参数说明:
select: 待返回的对象id,可以是一个id,也可以是一个id 列表。
· offset (optional): 参见search方法。
· limit (optional): 参见search方法。
返回值:返回对象或对象列表。
注意:本方法只能在Server上使用,由于效率等原因,不支持rpc等远程调用。

write方法:保存一个或几个记录的一个或几个字段。
格式:def write(self, cr, uid, ids, vals, context={})
参数说明:
· ids: 待修改的记录的id列表。
· vals: 待保存的字段新值,是一个字典,形如: {'name_of_the_field': value, ...}。
· context (optional): 参见create方法。
返回值:如果没有异常,返回True,否则抛出异常。
举例:self.pool.get('sale.order').write(cr, uid, ids, {'state':'cancel'})

unlink方法:删除一个或几个记录。
格式:def unlink(self, cr, uid, ids)
参数说明:
· ids: 待删除的记录的id列表。
返回值:如果没有异常,返回True,否则抛出异常。

default_get方法:复位一个或多个字段的缺省值。
格式: def default_get(self, cr, uid, fields, form=None, reference=None)
参数说明:
• fields: 希望复位缺省值的字段列表。
• form (optional): 目前似乎未用(5.06版)。
• reference (optional): 目前似乎未用(5.06版)。
返回值: 字段缺省值,是一个字典,形如: {'field_name': value, ... }。
举例:self.pool.get('hr.analytic.timesheet').default_get(cr, uid, ['product_id','product_uom_id'])

default_set方法:重置字段的缺省值。
格式: def default_set(self, cr, uid, field, value, for_user=False)
参数说明:
• field: 待修改缺省值的字段。
• value: 新的缺省值。
• for_user (optional): 修改是否只对当前用户有效,还是对所有用户有效,缺省值是对所有用户有效。
返回值: True

odoo开发基础--模型之基本字段类型的更多相关文章

  1. django中模型详解-字段类型与约束条件

    这片博文来详细说明django模型的使用,涉及到django模型的创建,字段介绍,以及django模型的crud操作,以及一对一等操作. 在使用模型之前,我们首先设置数据库选项,django的默认数据 ...

  2. odoo开发笔记--日期or时间字段给定默认值

    开发中经常有这样的场景,需要给某个日期或者时间的字段默认值: 例如: 日期,默认今天 时间,默认当前时间 可以在odoo模型定义中进行设置, 如下样例提供参考: test_data = fields. ...

  3. Mysql基础1-基础语法-字段类型

    主要: 基础 字段类型 基础 基本概念 1) 数据库分类 层次数据库,网状数据库,关系数据库 常见:SQL Server, Oracle,infomix,sybase,ibmDB2,Mysql 2)数 ...

  4. visio2003 数据表模型中显示字段类型和注释

    1.在visio菜单上选择 数据库->选项->文档. 2.在常规中找到 [在图表中可见的名称] 选中 两者. 3.在表中找到 [数据类型] 选中 显示物理. 4.在数据表模型中创建字段,并 ...

  5. Oracle开发:常用的数据库字段类型[转]

    Oracle常用的数据库字段类型如下: 字段类型 中文说明 限制条件 其它说明 CHAR 固定长度字符串 最大长度2000 bytes VARCHAR2 可变长度的字符串 最大长度4000 bytes ...

  6. odoo开发笔记--模型字段compute用法

    compute属性,实现的主要功能是,前端界面选择某个字段的时候,指定与该字段关联的其他字段可以关联,并联动的显示. 可以和inverse属性同时使用,不加inverse属性的话,前端界面的显示效果只 ...

  7. odoo开发笔记 -- 模型字段定义中设置默认值

    例如: company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env['res ...

  8. 【实习第十天】odoo开发基础整合

    前言 发文时间是2019年7月19日.提一下学习odoo的感受,odoo目前在国内并不是很流行,且主流是在企业型软件,所以导致目前odoo在网上的文献很少,学习相对来说比其他框架吃力.以下为大家总结1 ...

  9. odoo 开发基础 -- 视图之xpath语法

    odoo 视图函数 在整个项目文件中,结构并不是十分明显,虽然它也遵循MVC设计,类比django的MTV模式,各个模块区分的十分明显,在Odoo中,视图的概念不是特别明显,很多时候,我们会将调用模型 ...

随机推荐

  1. c# 二维list排序和计时

    using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using S ...

  2. Typecho 插件开发基础

    <?php /** * 标题 插件说明 * * @package 添加标题 * @author Fan * @version 1.0.0 * @link http://cnblogs.com/f ...

  3. 20171126--idleHadnler的理解使用

    相关参考文献: http://www.jianshu.com/p/94d6131a53b2 http://bbs.51cto.com/thread-1094228-1.html https://zhu ...

  4. (区间dp 或 记忆化搜素 )Brackets -- POJ -- 2955

    http://poj.org/problem?id=2955 Description We give the following inductive definition of a “regular ...

  5. (贪心 or DP)Woodcutters -- Codefor 545C

    http://codeforces.com/contest/545/problem/C  Woodcutters time limit per test 1 second memory limit p ...

  6. 2017-2018-1 20155326 《信息安全系统设计基础》第四周学习总结及myod改进版的补交

    2017-2018-1 20155326 <信息安全系统设计基础>第四周学习总结及myod改进版的补交 学习内容 补充完成课上没有完成的内容 学习教材附录A,第十章内容 参考别出心裁的Li ...

  7. 20155326 2016-2017-2 《Java程序设计》第十周学习总结

    20155326 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 计算机网络基础 1.计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的 ...

  8. USTC《现代软件工程》春季学期——第一次个人作业:词频统计

    截止日期 2018年3月29日23:59 要求 1. 对源文件(*.txt,*.cpp,*.h,*.cs,*.html,*.js,*.java,*.py,*.php等,文件夹内的所有文件)统计字符数. ...

  9. jQuery插件初级练习2答案

    html: $.font($("p"),"30px").html("变化了") jQuery: $.extend({ font:functi ...

  10. 关于Java-枚举的总结

    枚举 枚举的定义 枚举也是JDK5.0的新特性. JDK5.0加入了一个全新类型的“类”——枚举类型. 为此引入了一个新的关键字enum. 可以这样来定义一个枚举类型: public enum Col ...