当前位置: 首页 > 工具软件 > x-ORM > 使用案例 >

odoo-ORM API

姚昊焱
2023-12-01

odoo ORM API

基于odoo 12.0
odoo中的模型,一个很重要的特点就是,它即是定义模型的类,又是数据记录的集合,这一特性可以很方便的在模型中直接定义数据记录集的操作。例如赋值、修改、删除、计算等等。这些特性都需要odoo提供的ORM API来实现,具体方式是在函数定义前加上API的装饰器。

常用装饰器

  • @api.one:表示确定只有一条记录,模型类函数中self代表一条数据集,可直接采用self.<字段名>进行增查改删的操作吗,但是官方不提倡使用api.one装饰器

  • @api.multi:表示多条记录,此时函数的self代表的是一个数据集,通常可采用 for record in self 来循环对数据集操作,也可以使用self.ensure_one()函数达到api.one的目的。

  • @api.model:类装饰器,这里的self就不再是数据集,而是类本身,相当于python中的@classmethod,@api.model装饰器不能用于按钮的点击操作逻辑函数,应使用api.multi

  • @api.depends:用于计算字段,形式为@api.depends(‘field1’,‘field2’…),用于标示哪些字段参与了计算字段的计算,同时函数内计算字段必须被赋值,否则会报错

  • @api.constraints:用于评估和检查,使用形式同@api.depends,若记录修改时,检查不通过,则不会修改记录

  • @api.onchange:用于用户在交互时自动更新关联字段,self指的是一条记录,可返回一个报告修改信息字典{‘title’:‘message title’,‘message’:‘message body’}

ORM方法

orm操作数据集

  • 基本方法
    • <model>.create(values) :增
    • <model>.write(values) :改
    • <model>.unlink():删
      这三种模型写入数据的操作是models.Model自带的函数,用户可以根据需要重写该方法
  • shell命令
    启动odoo的shell调试器(需要安装watchdog包),在终端输出以下命令进入shell:
    odoo-bin shell -d (数据库名) -c /etc/odoo/odoo.conf #ubuntu or debian系统
    python odoo-bin shell -d (数据库名) #windows系统
    
    进入shell后,输入命令:
    >>>self
    res.users(1,)
    >>>self._name
    'res.users'
    >>>self.name
    'Administrator'
    
    shell中的self即为管理员账户,shell中可以通过env函数查询数据集:
    >>>self.env['res.users'].search([],limit=1)#通过模块名查找,如果不加limit=1,返回结果是一个列表
    res.users(1,)
    >>>self.env['sale.order'].browse()#通过模块名查找
    res.users(1,)
    >>>self.env.ref('base.user_root')#通过外部ID查找
    res.users(1,)
    
    self.env种包含了如下几个属性:
    • env.cr 当前数据库光标
    • env.user 当前会话用户的记录
    • env.uid 当前会话用户的ID,相当于env.user.id
    • env.context 会话的上下文不可变字典
    • env.sudo(user) 通过参数指定的用户返回用户所属的环境信息,如果不传参,默认返回管理员账户的环境
    • env.with_context(dict) 可以使用参数中的字典中的值给上下文环境中的值替换
    • env.with_context(key=value……) 同上

事务底层SQL

通过ORM API来执行数据库相关的操作:

self.env.cr.execute(sql)  #直接执行sql语句
self.env.cr.commit()   #用于提交本次事物
self.env.cr.savepoint()   #设置一个保存点用于回滚(rollback)
self.env.cr.rollback()    #取消当前操作,回滚到上次提交的点或者上一个保存点

示例:

>>>self.env.cr.execute('select id,login from res_users where login=%s or id=%s'.format('demo',1))
>>>self.env.cr.fetchall()
[(1,'admin'),(5,'demo')]

使用方法与其他的数据库orm api(pymysql,pyodbc等)类似。
此外,还可以运行数据库操作命令(DML),但odoo保存的是数据缓存,与数据库中的数据可能会不一致,因此在使用原是DML时,应该在完成后使用self.env.invalidate_all()清空这些缓存。

记录集的使用

  • context
    context是用字典储存的会话数据,在前端和服务器端都可以使用
    前端中,context可以叫信息从一个视图传递给另外一个视图,比如上一个窗体记录的ID,在俺就点击动作完成后传递给下一个窗体。
{'lan':'en_US','tz':'Europe/Brussels','uid':1}

服务器端,记录集可的字段值可以依赖context提供的本地设置,为服务器端提供一些信号信息。

当从一个窗体通过点击一个俺就打开另一个窗体时,关键字active_id(active_ids)将会加载到context中,记录了上一个窗体定位的记录id。active_model则记录的视图模型的技术名称。这在业务向导中经常用到。
例如在向导中要获取上一个记录的记录集,在对筛选的记录集在下一个窗体进行操作。实现过程为:在按钮的点击事件函数中,通过需要用到default_get()方法

@api.model
def default_get(self,feild_names):
	defaults = super(ModelClass,self).default_get(feild_names)
	defaults['ids'] = self.env.context('active_ids')
	return defaults

context在客户端可以用来设置目标视图的默认值或激活默认筛选器,使用default_或者default_search_开头的关键字来完成这种设置。

{‘default_user_id’:uid}
{‘default_search_filter_res_users’:1}
  • domain
    domain用于筛选记录集,domain使用的为domain表达式,形式为一个条件列表,每个条件都是一个元祖,如:
[('is_done','=',False)]   #[(<字段名>,<比较符>,<值>)]   

使用时需注意:

  1. 客户端使用时,当前视图的字段时可用,但不能使用点(.)连接这些字段使用
  2. 服务器端使用时,可以通过点连接
  3. 通常的比较符:<,>,<=,>=,=,!=
  4. =like:匹配模式,_表示任意字符,%表示任意字符串
  5. like:匹配模式,%value%
  6. child of:筛选子节点的值
  7. in和not in:包含不包含
  8. 与或非:使用’&’、’|’、’!‘一个或两个条件元祖构成,如[’&’,A,B]代表A&B,[’|’,A,B]代表A|B,多个与或非构成表达式,从后向前进行计算。

记录集的操作

查询模式

  • search方法,可以传递domain表达式进行筛选查询,其他参数还有order、limit及offset,分表代表对应的sql语句
  • browse方法:返回记录集的IDs或单个ID的列表方法。
  • search_count方法:只返回计数
  • name_search(): many2one字段搜索时调用
  • search_read(): many2one点开搜索更多时调用
  • read_group(): 搜索视图分组时调用

单例模式

只有一个记录的记录集成为单例,空记录也是单例。
对于单例模式,在开始时使用self.ensure_one()

写记录集

  • create方法:创建记录,传入字典参数
  • unlink方法:删除记录,不传入参数,直接用记录集调用
  • write方法:修改记录,传入字典参数

日期和时间

from odoo import fields
fields.Datetime.now()   ##时间
fields.Datetime.from_string('2018-01-01 00:00:00')
fields.Datet.today()    ##日期

操作记录集

record是一个记录集,可以对其进行一下操作

  • x in record 遍历记录集
  • x not in record 遍历记录集的他集
  • record.ids 返回记录集的id李彪
  • record.ensure_one() 返回单例记录集
  • record.filtered(func) 返回经过筛选的记录集
  • record.mapped(func) 返回经过映射值得列表
  • record.sorted(func) 返回有序的记录集
    非单例的记录集为一个列表,在服务器端可通过列表的方式进行操作

关系字段

  • 多对一、多对多:one_record.many_ids
  • 一对多: one_record.one_id
 类似资料: