ODOO学习笔记(12):自定义模块开发
一、Odoo模块结构基础
-
基本目录结构
- Odoo自定义模块通常有一个特定的目录结构。一个典型的模块目录包含以下文件和文件夹:
__init__.py
:这是一个Python模块初始化文件。它使得该目录被视为一个Python模块。在这个文件中,你可以通过from. import <python_file_name>
的方式导入模块中的其他Python文件。__manifest__.py
:这是模块的清单文件,用于定义模块的基本信息,如模块名称、版本、作者、依赖关系等。例如:{'name': 'My Custom Module','version': '1.0','author': 'Your Name','category': 'Uncategorized','description': """This is a custom module developed for specific business needs.""",'depends': ['base'], # 依赖基础模块'data': [# 在这里可以添加视图文件等数据文件的路径],'qweb': [# 添加QWeb模板文件路径] }
models
文件夹:用于存放模型(Model)相关的Python文件。模型定义了数据库中的表结构以及业务逻辑。例如,一个简单的自定义模型文件my_model.py
可能如下:from odoo import models, fields, apiclass MyModel(models.Model):_name ='my.model'name = fields.Char(string='Name')
views
文件夹:包含视图(View)相关的XML文件。视图用于定义用户界面,如表单视图、树视图等。一个简单的表单视图文件my_view.xml
可以是这样:<?xml version="1.0" encoding="UTF - 8"?> <odoo><record id="view_my_model_form_inherit" model="ir.ui.view"><field name="name">my.model.form.inherit</field><field name="model">my.model</field><field name="arch" type="xml"><form string="My Model Form"><field name="name"/></form></field></record> </odoo>
security
文件夹:用于定义安全相关的规则,如访问控制列表(ACL)。可以通过XML文件来定义哪些用户组可以访问特定的模型和视图等。
- Odoo自定义模块通常有一个特定的目录结构。一个典型的模块目录包含以下文件和文件夹:
-
模块的安装和升级
- 安装:在Odoo的应用商店界面(如果是企业版)或者在开发者模式下的模块列表中,找到自定义模块并点击安装。Odoo会根据
__manifest__.py
文件中的依赖关系先安装依赖的模块,然后创建数据库表(基于模型定义),加载视图等数据。 - 升级:当对模块进行修改后,如添加新的模型字段或者视图更改,升级模块时,Odoo会尝试根据修改的内容来更新数据库结构和视图等。例如,如果在模型中添加了一个新的字段,Odoo会在数据库表中添加对应的列。
- 安装:在Odoo的应用商店界面(如果是企业版)或者在开发者模式下的模块列表中,找到自定义模块并点击安装。Odoo会根据
二、模型开发(Model)
- 基础模型定义
- 继承基础模型:在Odoo中,很多时候我们会继承已有的模型来扩展功能。例如,继承
res.partner
(合作伙伴模型)来添加自定义字段。from odoo import models, fields, apiclass ResPartnerCustom(models.Model):_inherit ='res.partner'custom_field = fields.Char(string='Custom Field')
- 全新模型创建:定义新的模型,如创建一个任务管理模块的任务模型。
class Task(models.Model):_name = 'task.management.task'name = fields.Char(string='Task Name')description = fields.Text(string='Description')due_date = fields.Date(string='Due Date')
- 继承基础模型:在Odoo中,很多时候我们会继承已有的模型来扩展功能。例如,继承
- 模型关系定义
- 一对多关系:例如,一个项目(
project.project
)可以有多个任务(task.management.task
)。在任务模型中可以这样定义:class Task(models.Model):_name = 'task.management.task'#... 其他字段project_id = fields.Many2one('project.project', string='Project')
- 多对多关系:假设员工(
hr.employee
)可以属于多个项目团队,在员工模型中可以定义如下:class Employee(models.Model):_name = 'hr.employee'#... 其他字段project_team_ids = fields.Many2many('project.project.team', string='Project Teams')
- 一对多关系:例如,一个项目(
三、视图开发(View)
- 表单视图(Form View)
- 基本表单视图:用于显示和编辑单个记录。例如,一个简单的任务表单视图。
<?xml version="1.0" encoding="UTF - 8"?> <odoo><record id="view_task_form" model="ir.ui.view"><field name="name">task.management.task.form</field><field name="model">task.management.task</field><field name="arch" type="xml"><form string="Task Form"><sheet><group><field name="name"/><field name="description"/><field name="due_date"/></group></sheet></form></field></record> </odoo>
- 视图继承:可以继承已有的视图来添加或修改字段显示。例如,继承上面的任务表单视图来添加一个新字段。
<?xml version="1.0" encoding="UTF - 8"?> <odoo><record id="view_task_form_inherit" model="ir.ui.view"><field name="name">task.management.task.form.inherit</field><field name="model">task.management.task</field><field name="inherit_id" ref="module_name.view_task_form"/><field name="arch" type="xml"><field name="sheet" position="inside"><field name="new_field"/></field></field></record> </odoo>
- 基本表单视图:用于显示和编辑单个记录。例如,一个简单的任务表单视图。
- 树视图(Tree View)
- 树视图用于显示多个记录的列表。例如,一个任务列表树视图。
<?xml version="1.0" encoding="UTF - 8"?> <odoo><record id="view_task_tree" model="ir.ui.view"><field name="name">task.management.task.tree</field><field name="model">task.management.task</field><field name="arch" type="xml"><tree string="Task List"><field name="name"/><field name="due_date"/></tree></field></record> </odoo>
- 树视图用于显示多个记录的列表。例如,一个任务列表树视图。
四、业务逻辑开发
- 计算字段(Computed Field)
- 计算字段的值是根据其他字段的值通过一定的计算规则得到的。例如,在任务模型中计算任务的剩余天数。
from odoo import models, fields, apiclass Task(models.Model):_name = 'task.management.task'#... 其他字段due_date = fields.Date(string='Due Date')today_date = fields.Date(string='Today Date', default=fields.Date.today)remaining_days = fields.Integer(string='Remaining Days', compute='_compute_remaining_days')@api.depends('due_date', 'today_date')def _compute_remaining_days(self):for task in self:if task.due_date:task.remaining_days=(task.due_date - task.today_date).dayselse:task.remaining_days = 0
- 计算字段的值是根据其他字段的值通过一定的计算规则得到的。例如,在任务模型中计算任务的剩余天数。
- 约束条件(Constraints)
- 可以在模型中定义约束条件来确保数据的合法性。例如,确保任务的截止日期大于当前日期。
from odoo import models, fields, api from odoo.exceptions import ValidationErrorclass Task(models.Model):_name = 'task.management.task'#... 其他字段due_date = fields.Date(string='Due Date')@api.constrains('due_date')def _check_due_date(self):for task in self:if task.due_date and task.due_date < fields.Date.today():raise ValidationError("Due date must be greater than or equal to today's date.")
- 可以在模型中定义约束条件来确保数据的合法性。例如,确保任务的截止日期大于当前日期。