-
请先参考我的odoo二开(1)windows下环境配置教程,配置好环境,接下来会按照初始化直至这个模块能正确安装到你的odoo上为例展开,这里笔者的odoo版本是16,python版本是3.10.10,使用的环境是windows,很基础的操作这里不多赘述,大家自行百度。
-
到pycharm的terminal里输入
python odoo-bin scaffold D:\ERP\odoo-16.0\myAddons\myStudy
-
odoo-bin scaffold【后续都会叫他脚手架】会自动生成一个模块必要的所有文件和文件夹到指定的地址,还有一些展开参数,这里不做说明,可自行百度。
# -*- coding: utf-8 -*-
{
'name': "my_study",
'summary': """
测试学习模块""",
'description': """
测试学习模块</br><h1>报告上传模块测试</h1>
""",
'author': "phoney",
'website': "",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/16.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Services',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
# always loaded
'data': [
# 'security/ir.model.access.csv',
'views/views.xml',
'security/study_security.xml',
'security/ir.model.access.csv',
],
# only loaded in demonstration mode
'installable': True,
'application': True,
}
-
上面这段 manifest.py 代码解释:
- 一个名称为my_study的模块,依赖插件有base插件
- data字典表示:界面文件有 'views/views.xml',
- data字典表示:权限配置参考 'security/study_security.xml',
- data字典表示:权限文件是 'security/ir.model.access.csv',也方便初始化
上诉文件需要到模块目录下创建对应目录和文件
- 'installable': True, 是否可安装:是,这条影响能能不能手动安装。
- 'application': True, 是否是应用:是,这条影响插件能不能在应用模块里使用应用筛选条件直接搜索到。
-
接下来,先初始化models/models.py,即数据库初始化,这里用了一个检测报告模块做例子,考虑到一个检测报告需要文件名,上传人,订单号还有上传日期,以及一个可能需要的url,比较简单。
from odoo import models, fields, api
class my_study(models.Model):
_name = 'my_study.pzbg'
_description = '报告模块'
filename = fields.Char()
operator = fields.Char()
order = fields.Char()
upload_time = fields.Date()
url = fields.Char()
-
完成后开始着手准备相关界面'views/views.xml,下文属于准备视图的展示内容,简单可以理解为规划阶段
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record model="ir.ui.view" id="my_study_list">
<field name="model">my_study.pzbg</field>
<field name="arch" type="xml">
<tree string="study tree" editable="bottom">
<field name="filename" string="文件名"/>
<field name="operator"/>
<field name="order"/>
<field name="upload_time"/>
<field name="url"/>
</tree>
</field>
</record>
</data>
</odoo>
要点分析:
- <record>标签是odoo内定标签,其id属性是唯一标识符。
- record 的model属性里的ir.ui.view是说明这个record的使用的模型类型是ir_ui_view,数据库里会有对应的字段,odoo会在xml文件中使用一个点"."来代替数据库表名称中的下划线"_"。
- field标签name,model,arch属性,其中后两者是必填项,否则会报错 ,name随便起,model对应数据模型的name,arch的格式是固定的,你可以抄一些别的代码,里面填写你需要展示的内容具体排布情况。
- string属性:显示的是这个项的子标题。
- <field name="operator"/>不要写成 <field name="operator">xxx</field>这里新手容易犯错
-
继续编辑'views/views.xml,实现打开模型视图的功能,简单理解为修路阶段,光有规划没用,还得用路把规划和人连接起来。
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record model="ir.ui.view" id="my_study_list">
...省略了,就是上一块代码
</record>
<record model="ir.actions.act_window" id="my_study_tree_action_window">
<field name="name">my_study_action_window</field>
<field name="res_model">my_study.pzbg</field>
<field name="type">ir.actions.act_window</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="my_study_list"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">查询检测报告单
</p>
</field>
</record>
</data>
</odoo>
要点分析
- 同上,record里的数据模型model为ir.actions.act_window,这个window模型odoo有他的一套处理逻辑,将他合理的显示在页面中,不需要你过多操心。同理,以下field的内容均是这个模型的数据结构。
- field标签中name代表他的叫法,随便起一个就好。
属性res_model和view_mode的是必须项,其中:
- res_model对应你想指定的model对象,告诉程序你后续的view内容主要使用的是哪个数据模型。
- view_mode可选性有tree,和form,对应不同的表现形式
- tree代表树状视图,
2.form代表表单视图,就这么简单
- view_id 指向第六步定义的ir.ui.view数据模型类的view视图。
- help用来在没数据的时候给用户提供提示作用,选填
-
接下来为这个view视图添加菜单按钮,简单理解为修一个大门。
.
.
.省略节省空间,继续之前的代码写
<!-- 顶层菜单按钮,官方是这么解释的 -->
<menuitem name="检单查询" id="my_study.menu_root"/>
<!-- 第二级菜单-->
<menuitem name="报告展示方式" id="my_study.menu_1" parent="my_study.menu_root"/>
<!-- 第二级菜单的子菜单-->
<menuitem name="树状展示" id="my_study.menu_1_list" parent="my_study.menu_1"
action="my_study_tree_action_window"/>
<menuitem name="表单展示" id="my_study.menu_2_list" parent="my_study.menu_1"
action="my_study_form_action_window"/>
</data>
</odoo>
要点分析:
- menuitem 中只要id为模块名".menu_root"的,系统自动识别为系统菜单,企业版他会出现在桌面上,社区版我还没试过。
- 后续就基于这个root菜单一层一层搭建菜单就好,具体看上面的就行
- action 指向想要跳转的ir_act_window的record.id。
-
接下来初始化security/study_security.xml文件,来为用户赋予权限,这一步很重要,否则你后续安装好后无法找到插件了。
<?xml version="1.0" ?>
<odoo>
<record id="my_study_category" model="ir.module.category">
<field name="name">my_study</field>
</record>
<record id="my_study_group_user" model="res.groups">
<field name="name">my_studyUser</field>
<field name="category_id" ref="my_study_category" />
<field name="implied_ids" eval="[(4, ref('base.group_user'))]" />
</record>
<record id="my_study_group_manager" model="res.groups">
<field name="name">my_studyManager</field>
<field name="category_id" ref="my_study_category" />
<field name="implied_ids" eval="[(4, ref('my_study_group_user'))]" />
<field name="users" eval="[
(4, ref('base.user_root')),
(4, ref('base.user_admin'))
]" />
</record>
</odoo>
要点分析:
- 第一个record标签内是定义一个继承ir.module.category的model对象,用来在数据库ir_model_category表中生成一个分类,分类名是name属性对应的内容。
- 第二个record是在res.groups这个model创建一个my_studyUser的项,他的分类id刚好是第一个record
- implied_ids 这里的作用是odoo里的一个组权限继承机制,他的基础权限是继承的base.group_user这个组
- [(4, ...)]: 这是一个命令列表(command list),它是 Odoo 用于更新记录的关联字段的特定语法,这里的4的意思是新增,具体要查看odoo官方开发说明。
- *ref('base.group_user'):
ref 是一个函数,它返回给定外部 ID 的数据库记录的 ID。在这里,'base.group_user' 是一个外部 ID,它指的是 Odoo 基础模块(base)中的一个用户组。
- <field name="users" 里我将root,和user_admin用户默认定义到了my_study_group_manager这个组里。
-
新添加的模型还有一项必不可少的步骤,那就是配置加载权限。odoo使用的是csv文件,通过把csv文件里的列表数据加载到”ir.model.access”模型中实现。所以通常把这也的csv文件名称定义为”ir.model.access.csv”。
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
checkout_user,Checkout User,my_study.model_my_study_pzbg,my_study.my_study_group_user,1,1,1,0
checkout_manager,Checkout Manager,my_study.model_my_study_pzbg,my_study.my_study_group_manager,1,1,1,1
- 比较重要的是model_id这个项,这个是固定写法,规则是{模块名.model_模块名_类名},切记
- group_id:id:组id,上文提到的base.group_user是系统内置组,即员工.员工组,创建帐户时,默认属于这个组。所以给这个组赋权限,相当于给新帐户的默认权限,文中的则是在第9步中自定义的组,格式是模块名.组名。
- perm_read,perm_write,perm_create,perm_unlink:对应读、写、增加、删除权限,1是有权限,0是无权限,具体根据需要来设置权限
到这里一个模块就基本初始化完毕了