Odoo(2)odoo文件结构、模型字段、方法

665 阅读4分钟

一.odoo文件结构

项目名

->模块名
-->1. controller 访问路由控制
-->2. data 静态数据初始化(放快码.xml)
-->3. models 模型相关文件
--->(1)_init_.py 需要import 下述包
--->(2)包.py
-->4. static 前端文件
-->5. views 视图文件
-->6. wizard 向导文件
-->7. security 权限相关文件(.xml .csv)
-->8. i18n 翻译文件(zh_CN.po)
-->9. reports 报表文件(.py .xml)
-->10. _init_.py 需要import models
-->11. manifest.py 声明文件

二.odoo模型字段

(1)三种模型:

基本模型 models.Model(大多数情况)

瞬时模型 models.TransientModel(一般使用在导航形式的用户体验类中.临时模型的数据是临时存储在数据库中的,储存一定时间会被自动销毁,旧的数据会被新的数据直接取代,可用于报表。)

抽象模型 models.AbstractModel(它没有存储数据。在Odoo继承机制中作为一个混合类来增加新的功能。例如我们使用过的mail.thread模型)

(2)字段

1. 基础字段
  • Char 字符型
  • Text 文本类型
  • Boolean 布尔型
  • Integer 整数型
  • Float 浮点型 可用digits=(3,2)指定整数和小数位数
  • Monetary 金额型 小数默认显示两位,可用currency_field=''指定货币
  • Date 日期型
  • Datetime 日期时间型
  • Binary 二进制型
2. 复杂类型
  • Selection 选择型 selection属性可以是一个函数或者多值元组的列表
  • Reference
3. 关系类型
  • Many2one 多对一 需要comodel_name属性关联模型名,例如学生类有个'班级'字段
  • One2many 一对多 需要comodel_name属性关联模型名,需要inverse_name关联一个Many2one字段 例如班级类有个'学生'字段
  • Many2many 多对多 需要comodel_name属性关联模型名,等等
One2many和Many2many字段在数据写删上有一些特殊的写法:
  • (0, 0, {values}) 根据values的值新建一条记录
  • (2, ID, {values}) 更新id=ID的记录,(写入values的值)
  • (2, ID) 删除id=ID这条记录,(调用unlink方法,删除数据及整个主从数据链接关系)
  • (3, ID) 切断主从数据的链接关系但是不删除这个记录
  • (4, ID) 为id=ID的数据添加主从链接关系
  • (5) 删除所有的从数据的链接关系,也就是向所有的从数据调用(3, ID)
  • (6, 0, [IDs]}) 用IDs中的记录替换原来的记录(相当于先执行(5)在循环执行(4, ID))

(3)字段属性

  • string 字段描述
  • readonly 只读
  • required 必须
  • domain 域条件 如domain=['active','=',True]
  • invisible 可见
  • context 上下文 如context={'only_self':True}
  • selection [('',''),('','')]或者方法,在继承中,可以使用selection_add来扩展已经存在的下拉列表
  • copy 复制 缺省值为True,One2many字段默认为False
  • groups 用户组,声明指定仅对groups的用户组可见groups='base.base_user'
  • compute 该字段为计算字段,指定计算函数 如compute='_compute_value'
  • translate 值翻译
  • related 关联字段,用于关联一个Many2one字段的某一属性,一般都会同时添加readonly=True,根据情况添加store属性 如order_num = fields.Char(related='order_id.doc_number',readonly=True,store=True)
  • store 储存
  • track_visibility 字段变更记录 always onchange
  • relation 用于Many2many字段,声明中间表表名,可缺省

三.odoo模型方法

装饰器

@api.model 封装不关联数据记录的模型对象,用于与数据库记录无关的逻辑方法,例如:create,search方法。例:

# selection快码方法
@api.model
def _get_fund_source(self):
    return self.env['kthrp.base.lookup.value'].get_selection('study_research_fund_source')

@api.multi 封装关联多个数据记录的模型对象,用于与数据库记录关联的处理方法,最好函数内部手动遍历。write,unlink,copy,read方法。例:

@api.multi
def copy(self, default=None):
    default = dict(default or {})
    # one2many 字段的copy属性默认为false,所以当我们复制one2many字段时,可在字段定义处加copy=True,或在copy方法中赋值
    default['line_ids'] = [(6, 0, [line.copy().id or 0 for line in self.line_ids])]
    return super(KthrpStudyPurchaseOrder, self).copy(default)

@api.one 封装关联单条数据记录的模型对象,用于与单条数据库记录关联的处理方法,不建议使用 @api.depends('') 与compute字段配合使⽤用,当depends中的字段发生改变时便会触发该函数。若该compute字段 字段store=True,则depends字段在后台发生改变时,也会回写触发该函数,以保证compute字段在后台 储存的实时性。若字段在后台储存的实时性。若编写不当会导致效率问题,多多思考!!例:

@api.depends('budgeting_offset_ids')
def _compute_used_amount(self):
    self.used_amount = sum(self.budgeting_offset_ids.mapped('offset_amount'))
    self.remain_used_amount = self.release_amount - self.used_amount

@api.onchange('') 页面字段值变更触发

@api.onchange('bank_account_ids')
def onchange_bank_account(self):
    for rec in self:
        if len(rec.bank_account_ids) == len(rec.bank_account_ids.mapped('attachment_ids')):
            rec.attachment_flag = 'T'
        else:
            rec.attachment_flag = 'F'

@api.constrains 对添加数据自定义约束,强校验函数,当修改、写⼊、创建的数据中包含constrains字段便会触发该校验,此类函数很影响 效率,优先考虑其他实现方式。例:

# 设计文档中所有校验字段唯一性的,都是指在该模型字段中校验其唯一性
@api.constrains('code')
def check_code(self):
    for record in self:
        count_code = self.search_count([('code', '=', record.code)])
        if count_code > 1:
            raise ValidationError(_("Fund-10101: The code must be unique in the same business group!"))