一,ENVIRONMENT (ENV)
Environment 是 odoo 中操作db的总句柄,以下几种方式可以获得:
- 在 12,11,10,9,8版本中中,对于继承了Model的类来说可以直接通过self.env得到 Environment
- 在请求的 Controller 可以通过 request.env()得到 Environment
- 通过模型类或模型类对象获取,cls.env、product.env
eg 一些常用上下文参数:
当前用户
self.env.user
当前用户id
self.env.uid
当前语言代码
self.env.lang
当前数据库连接
self.env.cr
Environment用途示例
利用 env[model] 获取模型类对象
self.env['ir.model'].search([('state', '!=', 'manual')])
利用 env.cr 执行sql语句
self.env.cr.execute(query, (value,))
1.self是什么
目前新版的Odoo中使用到的self,是对 游标cr、用户ID、模型、上下文、记录集、缓存 的封装。
我们可以通过 self.XX 获取到这些封装的东西,比如:self.cr、self.uid。
2.通过直接设置属性来改变数据库中字段值
我们在查出某模型的记录后,可以通过 record.XX = value 来直接修改记录的字段内容。同样,在重写模型的write方法中,也可以通过 self.XX = value 来指定新增记录中某字段的值。
这里需要注意两点:
- 1:修改查出来的记录字段值来改变数据库内容,是通过改变缓存中的值出发数据库写记录来达到的。
- 2:重写write方法时,在write方法中每调用一次 self.XX = value 语句,都会触发数据库写操作,因此一般采用如下写法:
for rec in self:
rec.XX = XX
- 3:操作缓存
环境储存了模型的缓存记录集,因此我们可以通过环境来获取、增加、修改、删除记录,而触发数据库更改,从而达到操作数据库的目的。
例如:新增一条记录
self.env['模型'].create(vals)
- 4:不需要权限限制进行增删改查
我们可以通过self.sudo()获得超级权限,从而确保我们的操作能够进行。
test = self.env['my.example'].sudo().create({'id':1, 'name': 'test'})
- 5:更新缓存,触发数据库操作
self.env.invalidate_all()
二,Odoo常用ORM接口
1.普通查询:返回记录集,后续通过修改记录值来触发数据库修改
self.search(domain) //从当前模型的self中查询
self.env['model'].search(domain) // 获取某个model的环境,查询其中的记录集
demo = self.env['res.users'].search([('id','=',1)])
在res.users表中查找id=1的记录 返回的是一个res.users的对象
print demo.name
打印该对象中name
2.只读查询:返回列表,只能提取内容,不能触发数据库修改
self.search_read([],['要查询的字段'])
3.关联查询
student = self.env['emp.student']
teacher = self.env['emp.teacher']
demo = teacher.search([('id', '=', student.search([('id', '=', 1)]).teacher_id.id)])
print demo
print demo.name
print demo.sex#类似于sql中的嵌套查询
4.创建语句
demo.create({'name': "测试1" ,'stated': "说明1"})
#这个函数的意思就是在demo对象中,也就是res.user中插入一条记录
5.更新语句
rs = demo.search([('name', '=', client_id)])
info = {}
info[‘id’]=1
rs.write(info)#将制定的某条记录的数据进行一个更新
6.统计数量:返回符合条件的记录条数
self.search_count(domain)
7.浏览:通过一系列id值,返回对应的记录集
self.browse([id])
8.删除
test = self.env['sales.stargets.targetoption']#去获取sales_stargets_targetoption表为对象
test.search([('id', '=', 1)]).unlink()#将该表中id为1的记录删除掉
9.exists()
得到某个数据集中保留在数据库中的那部分,或在对一个数据集进行处理后重新赋值
if not record.exists():
raise Exception("The record has been deleted")
records.may_remove_some()
# only keep records which were not deleted
records = records.exists()
10.ref()
运行环境函数根据提供的external id返回对应的数据记录
>>> env.ref('base.group_public')
res.groups(2)
11.ensure_one()
检验某数据集是否只包含单条数据,如果不是则报错
records.ensure_one()
# 和下面的语句效果相同
assert len(records) == 1, "Expected singleton"
三,直接连接数据库
import psycopg2
db = psycopg2.connect(database="odoo", user="openerp", password="openerp", host="127.0.0.1", port="5432")
vals = db.cursor()
vals.execute("select id,name,list_price,area,feature,remark from product_template where id=1;")
tables = vals.fetchall()
for table in tables:
print table[0]
另一种操作数据的方式
sql = "select *from 表名"
self.env.cr.execute(sql) #执行SQL语句
dicts = self.env.cr.dictfetchall() #获取SQL的查询结果