Odoo中文网|Odoo实施培训

标题: odoo V10中文参考手册(一:ORM API) [打印本页]

作者: 店小2    时间: 2017-7-24 23:16
标题: odoo V10中文参考手册(一:ORM API)
本帖最后由 店小2 于 2017-7-24 23:33 编辑

记录集model的数据是通过数据集合的形式来使用的,定义在model里的函数执行时它们的self变量也是一个数据集合

  1. class AModel(models.Model):
  2.     _name = 'a.model'

  3.     def a_method(self):
  4.         # self can be anywhere between 0 records and all records in the database
  5.         self.do_operation()

  6.     def do_operation(self):
  7.     print self # => a.model(1, 2, 3, 4, 5)
  8.     for record in self:
  9.         print record # => a.model(1), then a.model(2), then a.model(3), ...

复制代码

获取有关联关系的字段(one2many,many2one,many2many)也是返回一个数据集合,如果字段为空则返回空的集合。
每个赋值语句都会触发数据库字段更新,同时更新多个字段时可使用或者更新多条记录时使用write函数
  1. # 3 * len(records) database updates
  2. for record in records:
  3.     record.a = 1
  4.     record.b = 2
  5.     record.c = 3

  6. # len(records) database updates
  7. for record in records:
  8.     record.write({'a': 1, 'b': 2, 'c': 3})

  9. # 1 database update
  10. records.write({'a': 1, 'b': 2, 'c': 3})
复制代码

# create partner object as administratorenv['res.partner'].sudo().create({'name': "A Partner"})# list partners visible by the "public" userpublic = env.ref('base.public_user')env['res.partner'].sudo(public).search([])常用ORM函数>>> self.search([('is_company', '=', True), ('customer', '=', True)])res.partner(7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74)>>> self.search([('is_company', '=', True)], limit=1).name'Agrolait'
如果只需要知道满足条件的数据数量,可以使用search_count()函数
if not record.exists():    raise Exception("The record has been deleted")records.may_remove_some()# only keep records which were not deletedrecords = records.exists()创建模型
模型字段就是定义的模型的属性,默认情况下字段名称就是属性名的大写,也可通过string参数指定
from odoo import models, fieldsclass AModel(models.Model):    _name = 'a.model.name'    field1 = fields.Char()    field2 = fields.Integer(string="an other field")可以通过default参数设置字段的默认值,默认值可以是特定的值,也可以指向一个函数
a_field = fields.Char(default="a value")def compute_default_value(self):    return self.get_value()a_field = fields.Char(default=compute_default_value)
  1. from odoo import api
  2. total = fields.Float(compute='_compute_total')

  3. @api.depends('value', 'tax')
  4. def _compute_total(self):
  5.     for record in self:
  6.         record.total = record.value + record.value * record.tax

复制代码


1.依赖的字段如果是子集里的字段,可用.表示
@api.depends('line_ids.value')def _compute_total(self):    for record in self:        record.total = sum(line.value for line in record.line_ids)
2.默认情况下实时计算的字段是不保存到数据库的,可以通过store=True参数来设置保存且可以搜索
3.可以为实时计算字段设置search参数来使其可搜索,参数的值须是一个返回domain表达式的函数
upper_name = field.Char(compute='_compute_upper', search='_search_upper')def _search_upper(self, operator, value):    if operator == 'like':        operator = 'ilike'    return [('name', operator, value)]
4.实时计算的字段也可以通过inverse参数来赋值,通过一个反转compute的函数来设置相关的字段值
  1. document = fields.Char(compute='_get_document', inverse='_set_document')

  2. def _get_document(self):
  3.     for record in self:
  4.         with open(record.get_document_path) as f:
  5.             record.document = f.read()
  6. def _set_document(self):
  7.     for record in self:
  8.         if not record.document: continue
  9.         with open(record.get_document_path()) as f:
  10.             f.write(record.document)
复制代码


5.多个字段可以同时使用同一个方法计算而来
  1. discount_value = fields.Float(compute='_apply_discount')
  2. total = fields.Float(compute='_apply_discount')

  3. @depends('value', 'discount')
  4. def _apply_discount(self):
  5.     for record in self:
  6.         # compute actual discount from discount percentage
  7.         discount = record.value * record.discount
  8.         record.discount_value = discount
  9.         record.total = record.value - discount

复制代码


6.关联字段
关联字段是实时计算字段的一个特例,它会给出子集对应的值,通过related参数来定义,就像普通字段一样可以保存到数据库
nickname = fields.Char(related='user_id.partner_id.name', store=True)
模型使用odoo的模型都是从class odoo.models.Model(pool, cr)继承而来
模型的属性结构:
1._name 业务对象的名称
2._rec_name 可选的name字段名称,供osv的name_get()方法使用,默认值name
3._inherit 如果设置了name属性,它的取值是单个或多个父级的模型名称;没有设置name属性时,只能是单个模型名称
4._order 在搜索的时候的默认排序,默认值是id
5._auto 指定该表是否需要创建,默认值是True,如果设置成False需要重写init方法来创建表
6._table 当_auto设置成false时,该值为创建的表名;默认情况下会自动生成一个
7._inherits 定义上级模型关联使用的外键
_inherits = {    'a.model': 'a_field_id',    'b.model': 'b_field_id'}8._sql_constraints 通过一个(name, sql_definition, message)的三元组列表定义表的sql级别约束
9._parent_store 与 parent_left , parent_right 一起使用,可得到一个嵌套的集合,默认是不启用的
CRUDSearching记录集合操作环境切换字段和视图查询其他方法内置字段保留字段一些字段名称是给model保留的,用来实现一些预定义的功能。当需要实现对应功能是需要对相应的保留字段进行定义
装饰器函数
模块提供了两种api形式,在传统形式中,所有参数明确地传给方法;还有一种记录行形式,提供了更加面向对象化的操作方式


  1. #传统方式:
  2. model = self.pool.get(MODEL)
  3. ids = model.search(cr, uid, DOMAIN, context=context)
  4. for rec in model.browse(cr, uid, ids, context=context):
  5.     print rec.name
  6. model.write(cr, uid, ids, VALUES, context=context)

  7. #新的记录行方式
  8. env = Environment(cr, uid, context) # cr, uid, context wrapped in env
  9. model = env[MODEL]                  # retrieve an instance of MODEL
  10. recs = model.search(DOMAIN)         # search returns a recordset
  11. for rec in recs:                    # iterate over the records
  12.     print rec.name
  13. recs.write(VALUES)                  # update all records in recs

复制代码


在传统方式下,通过某些参数自动应用了装饰方法
  1. @api.model
  2. def method(self, args):
  3.     ...

  4. #传统方式
  5. # recs = model.browse(cr, uid, ids, context)
  6. recs.method(args)

  7. model.method(cr, uid, args, context=context)
复制代码

  1. name = fields.Char(compute='_compute_pname')

  2. @api.one
  3. @api.depends('partner_id.name', 'partner_id.is_company')
  4. def _compute_pname(self):
  5.     if self.partner_id.is_company:
  6.         self.pname = (self.partner_id.name or "").upper()
  7.     else:
  8.         self.pname = self.partner_id.name
复制代码

@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错误,且不支持关联字段检验
self,args,*kwargs是在传统形式下需要传的参数
该装饰器将函数的输出变成api形式:传统形式下返回id/ids/false,记录形式下返回记录集合
  1. @model
  2. @returns('res.partner')
  3. def find_partner(self, arg):
  4.     ...     # return some record

  5. # output depends on call style: traditional vs record style
  6. partner_id = model.find_partner(cr, uid, arg, context=context)

  7. # recs = model.browse(cr, uid, ids, context)
  8. partner_record = recs.find_partner(arg)
复制代码

@api.v8def foo(self):...@api.v7def foo(self, cr, uid, ids, context=None):    ...











欢迎光临 Odoo中文网|Odoo实施培训 (http://www.chinaodoo.net/) Powered by Discuz! X3.2