odoo9.0---ORM API

来源:互联网 发布:mac 退出dashboard 编辑:程序博客网 时间:2024/06/08 01:05
-----记录集------
在模型中定义的方法在一个记录集中执行,他们的self就是一个记录集。
某一个模型(类)的所有对象(具体的实例)的集合就是一个Recordset对象。——这是recordset最大的情况,一个重要的限定条件就是其内元素必定是相同模型的,由这个最大的集合情况然后删除过滤掉一些元素(记录)之后仍然是recordset对象。

class AModel(models.Model):    _name = 'a.model'    def a_method(self):        # self可以是数据库中任意0或多个记录        self.do_operation()


迭代记录会产生新的单个记录集。
def do_operation(self):    print self # => a.model(1, 2, 3, 4, 5)    for record in self:        print record # => a.model(1), then a.model(2), then a.model(3), ...



字段访问
记录集提供一个“Active Record”接口,模型字段可以直接从记录集进行读写,但只在单个记录记录集中。给字段值设置一个触发器,使他进行数据库更新。
>>> record.nameExample Name>>> record.company_id.nameCompany Name>>> record.name = "Bob"


对记录集进行多次读写操作会引发异常。
同时对多个字段进行更新时,用write()方法
</pre><pre name="code" class="python"># 3 * len(records) database updatesfor record in records:    record.a = 1    record.b = 2    record.c = 3# len(records) database updatesfor record in records:    record.write({'a': 1, 'b': 2, 'c': 3})# 1 database updaterecords.write({'a': 1, 'b': 2, 'c': 3})


记录集是不可变的,但相同模型的记录可以通过操作符连接,返回新的记录集。


操作符
record in set:返回当前记录集中的记录。 
set1 <= set2 、set1 < set2:返回set1是否是set2的子集
set1 >= set2 、set1 > set2: 返回set1是否是包含set2的集合
set1 | set2 :返回两个集合的并集的新记录集。。
set1 & set2 :返回两个集合的交集的新记录集。
set1 - set2 :返回新记录集,其中只包括set1中有而set2中不存在的记录。


其他一些记录集操作

filtered():返回符合所给条件的记录。
# 只保留当前公司用户的记录。
records.filtered(lambda r: r.company_id == user.company_id)


# 只保留合伙人是公司的记录。
records.filtered("partner_id.is_company")


sorted():返回按所给关键字排序的记录。如果没有提供关键词,用默认排序。
# 通过名称关键字排序
records.sorted(key=lambda r: r.name)


mapped():对记录集中的记录应用所给方法,返回结果的记录集。
# 返回两个记录集中记录两两相加的结果的记录集。
records.mapped(lambda r: r.field1 + r.field2)


也可以通过字符串返回字段的值
# 返回名字的列表
records.mapped('name')


# 返回一个partner的记录集
record.mapped('partner_id')


#返回所有合作银行的集合, with duplicates removed
record.mapped('partner_id.bank_ids')


--------Environment----------
Environment 是 odoo 中操作db的总句柄。Environment存着很多ORM的上下文数据:数据库游标(用于数据库查询),当前用户(用于核对访问权限),当前上下文(存储任意数据)。Environment中也存储缓存。
所有记录集都有environment,是不可修改的,可以通过“env”得到,可以访问当前用户(user),游标(cr),或者上下文(context)。提供了注册访问,记录缓存,管理重新计算的数据结构。
>>> records.env<Environment object ...>>>> records.env.userres.user(3)>>> records.env.cr<Cursor object ...)


对于继承了Model的类来说可以直接通过self.env得到 Environment


在请求的 Controller 可以通过 request.env()得到 Environment


通过模型类或模型类对象获取,cls.env、product.env


一些常用属性列表:



返回当前用户 
self.env.user


返回当前用户id
self.env.uid


返回当前语言代码
self.env.lang


当前数据库连接
self.env.cr


返回是否处于草稿模式
self.env.in_draft


返回是否处于'onchange'草稿模式
self.env.in_onchange


应用例
1.利用env[model]获取类对象:
self.env['ir.model'].search([('state', '!=', 'manual')])
2.利用cr执行sql语句:
self.env.cr.execute(query, (value,))


改变Environment
Environment可以从一个记录集中被自定义。
sudo():通过提供的用户记录创建新的environment,# create partner object as administrator
env['res.partner'].sudo().create({'name': "A Partner"})


# list partners visible by the "public" user
public = env.ref('base.public_user')
env['res.partner'].sudo(public).search([])


with_context():可接受单个定位参数,来替换当前env的上下文;可以根据关键字接受任意个参数,然后添加到当前的env的上下文。
# look for partner, or create one with specified timezone if none is found
env['res.partner'].with_context(tz=a_tz).find_or_create(email_address)

——————————————----------------
<field name="name" on_change="0"/>
添加onchange=“0”属性,就不执行onchange。
--------------------------------------------------------------



one装饰器的作用是对每一条记录都执行对应的方法,无返回值。



model装饰器的作用是返回一个集合列表,一般用来定义自动化动作里面,该方法无ids传入。
@api.modeldef some_method(self, a_value):    pass# can be called asold_style_model.some_method(cr, uid, a_value, context=context)


constrains装饰用于对字段进行限制
@api.constrains('age')def _check_age(self):    if self.age<16:        raise ValueError(_('Age must be older than 16'))


multi装饰器
的作用是对每一条记录都执行对应的方法,与one装饰类不同的是有返回值。


depends装饰  
  
1.在计算字段值(而不是直接从数据库中读取)时使用的计算参数。它必须将计算值分配给该字段。如果使用其他字段的值,应该使用depends()指定这些字段  
实例:  
    total=fields.Float(compute=“compute_total”)  @api.depends('value','tax)        def compute_total(self):          for record in self:              record.total=record.value+record.value*record.tax  

  
2. 当使用关联字段是可以指名路径:  
实例:  
    @api.depends('line_ids.values')      def compute_total(self):          for record in self:              record.total=sum([line.value for line in record.line_ids]) 


onchange装饰  

当用户更改某个字段的值时(但尚未保存该表单),他可以自动更改基于该字段的字段值,如更改或添加一个新的发票行时,该值自动更新 


returns()装饰   
返回一个对象的集合,第一个参数是记录的模型名字或是self(当前模型)
>>> @api.multi... @api.returns('self')... def some_method(self):...     return self>>> new_style_model = env['a.model'].browse(1, 2, 3)>>> new_style_model.some_method()a.model(1, 2, 3)>>> old_style_model = pool['a.model']>>> old_style_model.some_method(cr, uid, [1, 2, 3], context=context)[1, 2, 3]


One2many,Many2many使用特殊的“命令”格式来操作设置的字段。这种格式是三元的,(This format is a list of triplets executed sequentially, where each triplet is a command to execute on the set of records. Not all commands apply in all situations.) Possible commands are:
(0, _, values)
从所给value的字典中添加一条新纪录
(1, id, values)
更新一条已有记录,id为:id,更新内容为values。Can not be used in create().
(2, id, _)
移走id为“id”的记录,并从数据库中删除。Can not be used in create().
(3, id, _)
移走id为“id”的记录,但并不从数据库中删除。 Can not be used on One2many. Can not be used in create().
(4, id, _)
向id为“id”记录处添加已有记录。 Can not be used on One2many.
(5, _, _)
从记录集中删除所有数据, Can not be used on One2many. Can not be used in create().
(6, _, ids)
用ids列表中的所有记录替换原有记录。 Can not be used on One2many.


注:标记为“_”的值可以为任意值,通常为“0”或“False”。














 
0 0