一、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, api class 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, api class 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, api class 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).days else: task.remaining_days = 0
- 计算字段的值是根据其他字段的值通过一定的计算规则得到的。例如,在任务模型中计算任务的剩余天数。
- 约束条件(Constraints)
- 可以在模型中定义约束条件来确保数据的合法性。例如,确保任务的截止日期大于当前日期。
from odoo import models, fields, api from odoo.exceptions import ValidationError class 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.")
- 可以在模型中定义约束条件来确保数据的合法性。例如,确保任务的截止日期大于当前日期。