运行时依赖
安装命令
点击复制技能文档
SKILL.md — huo15-odoo19-module-dev 触发条件 用户提到以下内容时激活本技能: Odoo19 模块开发 开发 Odoo 模块 Odoo 模型/视图/业务逻辑 Odoo manifest / __manifest__.py Odoo 插件安装 Odoo XML/JS/CSS 资源 Odoo 模块开发核心概念 模块结构(标准化) my_module/ ├── __init__.py # 模块导入声明 ├── __manifest__.py # 元数据清单(必需) ├── models/ │ ├── __init__.py │ └── models.py # 所有模型定义 ├── views/ │ ├── views.xml # 视图定义 │ └── templates.xml # Web 模板 ├── security/ │ └── ir.model.access.csv ├── data/ │ └── demo.xml # 演示数据 ├── controllers/ │ ├── __init__.py │ └── controllers.py # HTTP 路由 ├── wizards/ │ ├── __init__.py │ └── wizard.py # 向导/向导模型 └── static/ ├── src/xml/ # JS/QWeb 模板 ├── src/js/ # JavaScript └── src/css/ # CSS __manifest__.py 最小模板 { 'name': "我的模块", 'version': '1.0.0', 'summary': '模块一句话描述', 'description': """ 模块详细说明(多行) """, 'category': 'Hidden', # Hidden/Productivity/Manufacturing/... 'author': '火一五信息科技', 'website': 'https://www.huo15.com', 'license': 'LGPL-3', 'depends': ['base'], 'data': [ 'security/ir.model.access.csv', 'views/views.xml', ], 'installable': True, 'application': False, } 模型开发(Model) 基本模型模板 from odoo import models, fields, api from odoo.exceptions import ValidationError class MyModel(models.Model): _name = 'my.model' # 必填,点分格式 _description = '我的模型' # 模型描述 _order = 'sequence, id' # 默认排序 _inherit = [] # 继承,可为空列表 name = fields.Char( string='名称', required=True, index=True, help='这是帮助文本' ) active = fields.Boolean( string='活跃', default=True, index=True ) description = fields.Text(string='描述') date = fields.Date(string='日期') datetime = fields.Datetime(string='时间') # 关联字段 partner_id = fields.Many2one( 'res.partner', string='客户', index=True, ondelete='cascade' # cascade/restrict/set null ) line_ids = fields.One2many( 'my.model.line', 'parent_id', string='明细行' ) # 计算字段 amount_total = fields.Float( string='合计', compute='_compute_amount', store=True # 存储以便搜索 ) # 状态字段 state = fields.Selection([ ('draft', '草稿'), ('confirm', '已确认'), ('done', '完成'), ('cancel', '已取消'), ], string='状态', default='draft', index=True) # SQL 约束 _sql_constraints = [ ('name_unique', 'UNIQUE(name)', '名称不能重复!'), ] @api.constrains('name') def _check_name(self): for record in self: if not record.name: raise ValidationError('名称不能为空') @api.depends('line_ids.price', 'line_ids.qty') def _compute_amount(self): for rec in self: rec.amount_total = sum( line.price * line.qty for line in rec.line_ids ) 关系字段对比 字段类型 语法 用途 Many2one fields.Many2one('other.model', ...) 多选一(外键) One2many fields.One2many('other.model', 'rel_field', ...) 一对多 Many2many fields.Many2many('other.model', ...) 多对多 Reference fields.Reference(...) 可变模型引用 常用字段参数 # 通用参数 string='标签' # UI 显示名 required=True # 必填 index=True # 数据库索引 help='提示文本' # 鼠标悬停提示 default=... # 默认值 copy=True/False # 复制时是否带值 readonly=True # 只读 store=True # 存储到数据库(计算字段) tracking=True # 变更追踪(邮件通知) # Char size=200 # 最大长度(旧版,新版已废弃) translate=True # 允许翻译 # Numeric digits=(16, 2) # 总位数,小数位 # Date/Datetime calendar='gregorian' # 日历类型 # Selection selection=[('a','A'),('b','B')] # 选项列表 核心 API 方法 # 创建 record = self.env['my.model'].create({'name': 'value'}) # 搜索 records = self.env['my.model'].search([ ('active', '=', True), ('name', 'like', 'test%'), ]) # 读取 record.read(['name', 'active']) record.mapped('partner_id.name') # 提取字段 # 写入 record.write({'name': 'new name'}) # 删除 record.unlink() # 复制 record.copy() # 过滤 filtered = records.filtered(lambda r: r.active) # 排序 sorted_records = records.sorted(key=lambda r: r.create_date) 模型方法覆盖 class SaleOrder(models.Model): _inherit = 'sale.order' # 覆盖 # 覆盖 create 方法 @api.model def create(self, vals): # 添加默认值或预处理 vals['client_order_ref'] = vals.get('name', '') return super().create(vals) # 覆盖 write 方法 def write(self, vals): # 业务逻辑 if 'state' in vals and vals['state'] == 'sale': self.mapped('order_line').write({'state': 'sale'}) return super().write(vals) # 按钮方法 def action_confirm(self): for order in self: if not order.partner_id: raise ValidationError('请先选择客户') order.write({'state': 'sale'}) return True # 动作返回 def action_view_invoice(self): # 返回视图 return {