odoo会为记录保留一份缓存,它有一种内置的预读取机制,通过缓存来提升性能。
记录集API
model 中的数据是以集合的形式使用的,因此可以使用集合运算来操作。
集合运算符
- record in set : 返回record 是否在set中,record须为单条记录,record not in set 反之
- set1<= set2 :返回set1是否为set2的子集
- set1 >= set2 返回set2是否为set1的子集
- set1 | set2 返回set1和set2的并集
- set1 & set2 返回set1和set2的交集
- set1 - set2 返回在集合set1中但不在set2中的记录
集合运算API
- ids 得到当前记录集合的id列表
- ensure_one()验证一个记录集合是否只包含一条记录
- exists() 返回当前记录集中真正存在的子集,并把缓存中未删除的部分做标记,可用于判断if record.exists():
- filtered(func) 返回满足func 参数内条件的记录集合,参数可以是一个函数或者用,分割的字段列表
//only keep records whose company is the current user's
records.filtered(lambda r: r.company_id == user.company_id)
//only keep records whose partner is a company
records.filtered("partner_id.is_company")
- sorted(key=None, reverse=False) 返回按key排序之后的记录集,key参数可以是一个返回单个key的函数或字段名称或为空,reverse参数为True时即为倒序
# sort records by name
records.sorted(key=lambda r: r.name)
- mapped(func) 将func函数应用到所有记录上,并返回记录列表或集合
#returns a list of summing two fields for each record in the set
records.mapped(lambda r: r.field1 + r.field2)
#函数也可以是字符串 对应记录的字段
#returns a list of names
records.mapped('name')
#returns a recordset of partners
record.mapped('partner_id')
运行环境API
运行环境保存了很多orm相关的变数:数据库查询游标,当前用户,元数据,还有缓存,可使用env来访问,如:
records.env.user 获取当前用户
records.env.cr 获取当前游标
records.env.context 当前的上下文
更改运行环境
- sodu() 使用现有的数据集创建一个新的运行环境,得到一个基于新运行环境的数据集的拷贝
env[‘res.partner‘].sudo().create({‘name‘: "A Partner"})
-
with_context()
一个参数时可用于替换当前运行环境的context,多个参数时通过keyword添加到当前运行环境context或单参数时设置的context -
with_env() 完整替换当前运行环境
ORM API
- search()
接收domain表达式参数,返回符合条件的数据集合,可以通过limit,offset参数返回一个子集,还可通过order参数对数据排序。
self.search([(‘is_company‘, ‘=‘, True), (‘customer‘, ‘=‘, True)])
self.search([]) // 查询所有
- search_count()
统计满足条件的数据数量
- create()
接收多个字段、值的组合,返回新创建的数据集:
self.create({‘name‘: "New Name"})
- write()
接收多个字段、值组合,会对指定数据集的所有记录进行修改,不返回:
self.write({‘name‘: "Newer Name"})
- browse()
根据数据的id或者一组id来查找,返回符合条件的数据集合:
self.browse([7, 18, 12])
- exists()
得到某个数据集中保留在数据库中的那部分(可用于检查数据集是否为空):
if not record.exists():
raise Exception("The record has been deleted")
- ref()
运行环境函数,根据提供的外部id返回对应的数据记录:
env.ref('base.group_public')
res.groups(2)
- ensure_one()
检验某数据集是否只包含单条数据,如果不是则报错:
records.ensure_one()
装饰器函数
模块提供了两种api形式,在传统形式中,所有参数明确地传给方法;还有一种记录行形式,提供了更加面向对象化的操作方式
//传统方式:
model = self.pool.get(MODEL)
ids = model.search(cr, uid, DOMAIN, context=context)
for rec in model.browse(cr, uid, ids, context=context):
print rec.name
model.write(cr, uid, ids, VALUES, context=context)
//新的记录行方式
env = Environment(cr, uid, context) # cr, uid, context wrapped in env
model = env[MODEL] # retrieve an instance of MODEL
recs = model.search(DOMAIN) # search returns a recordset
for rec in recs: # iterate over the records
print rec.name
recs.write(VALUES) # update all records in recs
在传统方式下,通过某些参数自动应用了装饰方法
- odoo.api.multi(method)
在记录行方式下装饰一个对记录进行操作的方法
@api.multi
def method(self, args):
...
#传统方式下使用方式
#recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, ids, args, context=context)
- odoo.api.model(method)
在记录行方式下装饰一个内容不明确、但模型明确的方法
@api.model
def method(self, args):
...
#传统方式
#recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, args, context=context)
- odoo.api.depends(*args)
返回为compute方法指定依赖字段的装饰器,每个参数必须是字符串
name = fields.Char(compute='_compute_pname')
@api.one
@api.depends('partner_id.name', 'partner_id.is_company')
def _compute_pname(self):
if self.partner_id.is_company:
self.pname = (self.partner_id.name or "").upper()
else:
self.pname = self.partner_id.name
- odoo.api.constrains(*args)
装饰一个约束检查方法,每个参数必须是需要检查的字段
@api.one
@api.constrains('name', 'description')
def _check_description(self):
if self.name == self.description:
raise ValidationError("Fields name and description must be different")
在检验失败时抛出ValidationError错误,且不支持关联字段检验
- odoo.api.onchange(*args)
返回一个监控指定字段的onchange方法的装饰器,每个参数必须是字段名称
@api.onchange('partner_id')
def _onchange_partner(self):
self.message = "Dear %s" % (self.partner_id.name or "")
该函数可能会返回 以数据字典形式组装的当前更改字段的domain表达式和一个警告消息,不支持关联字段处理
return {
'domain': {'other_id': [('partner_id', '=', partner_id)]},
'warning': {'title': "Warning", 'message': "What is this?"},
}
- odoo.api.returns(model, downgrade=None, upgrade=None)
返回一个获取model实例的方法的装饰器
参数列表
model 模型名称,self代表当前模型
downgrade 一个将value值从记录形式转化为传统形式的方法:downgrade(self, value, *args, **kwargs)
upgrade 一个将value从传统形式转化为记录形式的方法:upgrade(self, value, *args, **kwargs)
self,args,*kwargs是在传统形式下需要传的参数
该装饰器将函数的输出变成api形式:传统形式下返回id/ids/false,记录形式下返回记录集合
@model
@returns('res.partner')
def find_partner(self, arg):
... # return some record
#output depends on call style: traditional vs record style
partner_id = model.find_partner(cr, uid, arg, context=context)
#recs = model.browse(cr, uid, ids, context)
partner_record = recs.find_partner(arg)
- odoo.api.one(method)
装饰一个需要将self作为单例模式使用的记录形式方法,该方法自动对记录进行循环并将结果组织成列表,当记录行被returns方法装饰过时,该方法会将对应的实例组织起来,从9.0版本开始不用了.