文章目录
- Odoo(旧名字:OpenERP)
- 常见缩写
- Odoo介绍
- odoo常用方法:
- 一 搭建以及了解Odoo开发环境
- 1 Odoo生态系统
- 2 从源码轻松安装Odoo
- 3 使用start命令管理Odoo环境
- 4 管理Odoo服务端数据库
- 5 在一个文件中存储实例配置
- 6 激活Odoo开发者工具
- 7 从源码更新Odoo
- 二 管理Odoo服务器实例
- 1 配置插件路径
- 2 更新插件模块列表
- 3 标准化你的实例目录布局
- 4 安装并升级本地插件模块
- 5 对插件应用修改
- 6 应用及尝试建议的拉取请求
- 三 服务器部署
- 1 安装Odoo来供生产使用
- 2 为生产环境调整配置文件
- 3 设置Odoo来作为系统服务
- 4 使用nginx和Let‘s Encrypt配置反向代理及SSL
- 5 使用Docker来运行Odoo
- 6 通过docker-compose运行Odoo
- 7 管理网站的内容分发网络(CDN)
- 四 创建Odoo插件模块
- 1 创建和安装一个新的插件模块
- 2 完成插件模块的声明
- 3 组织插件模块文件结构
- 4 添加模型
- 5 添加菜单项和视图
- 6 添加访问权限
- 7 使用脚手架命令来创建模块
- 五 应用模型
- 1 定义模型表现及顺序
- 2 向模型添加数据字段
- 3 使用可配置精度的浮点字段
- 4 向模型添加货币字段
- 5 向模型添加关联字段
- 6 向模型添加等级
- 7 向模型添加约束验证
- 8 向模型添加计算字段
- 9 暴露存储在其它模型中的关联字段
- 10 使用引用字段添加动态关联
- 11 使用继承向模型添加功能
- 12 为可复用模型功能使用抽象模型
- 13 使用代理继承将功能拷贝至另一个模型
- 六 基本服务端开发
- 1 定义模型方法及使用API装饰器
- 2 向用户报出错误
- 3 为不同模型获取一个空记录集
- 4 新建记录
- 5 更新记录集中记录值
- 6 搜索记录
- 7 合并记录集
- 8 过滤记录集
- 9 遍历记录集关联
- 10 记录集排序
- 11 继承模型中定义的业务逻辑
- 12 继承write()和create()
- 13 自定义记录的搜索方式
- 14 通过read_group()获取组中的数据
- 七 模块数据
- 1 使用外部ID和命名空间
- 2 使用XML文件加载数据
- 3 使用noupdate和forcecreate标记
- 4 使用CSV文件加载数据
- 5 插件更新和数据迁移
- 6 从XML文件中删除记录
- 7 从XML文件中调用函数
- 八 调试
- 1 自动加载和--dev 选项
- 2 产生服务日志来帮助调试方法
- 3 使用Odoo shell来交互调用方法
- 4 使用Python调试器来追踪方法执行
- 5 使用Odoo社区联盟维护者质量工具
- 6 理解调试模式选项
Odoo(旧名字:OpenERP)
常见缩写
-c :config,指定配置文件
-d :db,指定数据库
-u :update,更新
-p :python,指定python版本
Odoo介绍
https://zhuanlan.zhihu.com/p/68931020
https://www.zhihu.com/question/54535673/answer/263500692
- 1 Odoo,是一个企业应用软件套件,开源套件包括一个企业应用快速开发平台+几千个Odoo及第三方开发的企业应用模块。
- 2 Odoo功能模块涵盖了各方面的企业应用:CRM、订单处理(销售订单和采购订单)、电子商务、MRP、财务、库存、门店零售、项目管理等等。
- 3 它是基于一个模块化、可扩展和直观的快速开发应用程序(RAD)的框架,使用Python语言。
- 4 OpenObject功能对象集成-关系映射(ORM),基于模板的模型-视图-控制器(MVC)接口,报表生成系统,多国语言,快速构建应用程序;是一个完整的模块化的工具。
- 5 Odoo是一个支持多用户的三层架构:
- 数据库层:数据存储(M)
- 应用层:处理和提供业务功能(C)
- 表现层:提供用户界面(V)
- 6 架构模式(MVC):模型-视图-控制器
- 7 Odoo系统主要由三个部分组成:
- PostgreSQL数据库服务器包含所有Odoo数据库。
- Odoo服务器包含所有的企业逻辑,确保Odoo的优化运行。
- 其中一层是ORM引擎,专门与PostgreSQL数据库通信。
- 另外一层是Web层,控制服务器和Web浏览器通信。
- 客户端运行在web浏览器中,是JavaScript应用程序。
- 开发语言:Python,视图:xml
odoo常用方法:
create(dics):在数据表中插入一条记录,返回新对象
search(domain):查询符合条件的对象列表,返回对象列表。
search(domain, limit=1):返回一个对象
search_read(domian, fields):返回指定的fields的字典列表。
search(domain).read(fields):返回记录集的指定字段值列表,返回字典列表。
browse(id):浏览对象及其关联对象,返回对象
browse([ids]):返回对象列表
browse(id).read(fields):返回记录的指定字段值列表,返回字典
write(dics):保存一个或几个记录的一个或几个字段,返回True或False
default_get:复位一个或多个字段的缺省值
default_set:重置字段的缺省值
一 搭建以及了解Odoo开发环境
每一小节讲解流程:
准备工作 —> 如何操作 —> 运行原理 —> 扩展知识
1 Odoo生态系统
2 从源码轻松安装Odoo
3 使用start命令管理Odoo环境
4 管理Odoo服务端数据库
5 在一个文件中存储实例配置
6 激活Odoo开发者工具
7 从源码更新Odoo
二 管理Odoo服务器实例
这章主要讲解如何创建Odoo服务器实例,实例对应的插件,以及对插件的安装、升级、修改
1 配置插件路径
2 更新插件模块列表
3 标准化你的实例目录布局
4 安装并升级本地插件模块
当心依赖的处理。假定有一个实例需要安装sale、sale_stock、sale_specific插件,sale_specific依赖于sale_stock,而sale_stock依赖于sale。
要安装这三者,只需要安装sale_specific,因为它会递归安装sale_stock和sale这两个依赖。
要升级这两者,只需要升级sale,因为它会递归升级其反向依赖,即递归升级sale_stock和sale_specific。
5 对插件应用修改
6 应用及尝试建议的拉取请求
三 服务器部署
1 安装Odoo来供生产使用
2 为生产环境调整配置文件
3 设置Odoo来作为系统服务
4 使用nginx和Let‘s Encrypt配置反向代理及SSL
5 使用Docker来运行Odoo
容器技术
6 通过docker-compose运行Odoo
7 管理网站的内容分发网络(CDN)
CDN通过在地理上非常近的服务器提供静态资源的服务来降低网站的加载时间。
1 配置CDN提供商
2 在Odoo上配置CDN
四 创建Odoo插件模块
1 创建和安装一个新的插件模块
2 完成插件模块的声明
__manifest__.py
3 组织插件模块文件结构
.
├── __init__.py
├── __manifest__.py # 模块声明文件
├── controllers # 包含网页控制器的代码文件,用于为模块提供各种功能
│ └── __init__.py
├── data # 包含模块初始数据的其他数据文件
├── demo # 带演示(预加载)数据的数据文件
├── i18n # 存放翻译文件
├── models # 存放创建模型及其业务逻辑文件
│ └── __init__.py
├── static # 放置所有的网页资源
│ └── description
│ └── icon.png
└── views # 存放定义视图的xml文件
|
└── security # 定义访问控制列表的数据文件
4 添加模型
models
文件夹下
5 添加菜单项和视图
在views
文件夹下
6 添加访问权限
security
文件夹下创建对应的groups.xml
定义组和ir.model.access.csv
通过组来关联模型的权限
7 使用脚手架命令来创建模块
scaffold
命令
五 应用模型
1 定义模型表现及顺序
将模型字段在xml中进行描述,模型中使用_order指定顺序,_descriptions、_rec_name
2 向模型添加数据字段
Char、Float、Integer、Boolean、Binary、Date、Datetime、Text、Selection、Html、Many2many、One2many、Many2many、Monetary、Reference
3 使用可配置精度的浮点字段
Float(string=‘xxx’,digits=(a,b))
4 向模型添加货币字段
Monetary(string=‘xxx’,currency_field=‘field_name’)
5 向模型添加关联字段
Many2one(comodel_name=‘related_table’,string=‘xxx’)
One2many(comodel_name=‘related_table’,inverse_name=‘inverse_field_name’,string=‘xxx’)
Many2many(comodel_name=‘related_table’,relation=‘two_table_name’,column1=‘xxx’,column2=‘xxx’,string=‘xxx’)
6 向模型添加等级
创建一个等级分类的树结构用于提高查询速度
@api.constrains(‘field_name’)
def …
7 向模型添加约束验证
1 数据库级别的约束检查:PG所支持的约束,例如UNIQUE、CHECK、EXCLUDE
# 添加模型属性才创建数据库约束:书名不可以重复 _sql_constraints = [ ('name_uniq', 'UNIQUE (name)', 'Book title must be unique') ]
2 服务级别的约束检查:编写Python代码来使用Odoo服务级别的约束
# 发布日期不可以超过当天日期时间 @api.constrains('date_release') def _check_release_date(self): for record in self: if record.date_release and record.date_release > fields.Date.today(): raise ValidationError('Release date must be in the past')
8 向模型添加计算字段
带有compute参数的字段,根据api.depends(‘xxx’)指定的依赖字段xxx编写对应的计算方法去获得本身字段的值。
inverse反向方法参数作用是根据当前字段的值改变api.depends(‘xxx’)中指定的xxx字段的值
9 暴露存储在其它模型中的关联字段
在字段中添加属性related=‘otherfield_otherfield’
10 使用引用字段添加动态关联
fields.Reference(selection=‘func_name’,string=‘xxx’)
11 使用继承向模型添加功能
_inherit=‘model_name’
_inhert=[‘model_name’,‘model2_name’,]
12 为可复用模型功能使用抽象模型
AbstractModel
13 使用代理继承将功能拷贝至另一个模型
_name = ‘new_model_name’
_inherts = [‘model_name’]
传统继承和委托继承的区别如下:
六 基本服务端开发
1 定义模型方法及使用API装饰器
使用def xxx定义模型方法
使用装饰器装饰模型方法
在视图中通过button标签的name属性去调用模型方法
2 向用户报出错误
from odoo.exceptions import UserError
from odoo.tools.translate import _ # 支持翻译的一个函数
error_msg = _(‘error_message %s’) % ‘your error’
raise UserError(error_msg)
3 为不同模型获取一个空记录集
self.env[model]的使用
4 新建记录
create(dics),返回创建的对象
5 更新记录集中记录值
1 self.field_name=‘xxx’
2 self.update({‘field_name’:‘value’,…})
3 self.write(dics),返回True或者False
6 搜索记录
search(self, args, offset=0, limit=None, order=None, count=False)。
search(domain):查询符合条件的对象列表,返回对象列表。
search(domain, limit=1):返回一个对象
search_read(domian, fields):返回指定的fields的字典列表。
search(domain).read(fields):返回记录集的指定字段值列表,返回字典列表。
browse(id):浏览对象及其关联对象,返回对象
browse([ids]):返回对象列表
browse(id).read(fields):返回记录的指定字段值列表,返回字典
7 合并记录集
result = recordset1 + recordset2
result = recordset1 | recordset2
result = recordset1 & recordset2
运算符:+、-、&、|、==、(A <= B) 等价于(A in B)、(A >= B)等价于(B in A)、!=、
赋值运算符:+=、-=、&=、|=
8 过滤记录集
记录集对象.filter()
9 遍历记录集关联
mapped(self,func or field name)
10 记录集排序
sorted(key,reverse)
11 继承模型中定义的业务逻辑
super(),通过super去调用父类的方法,并为父类的该方法添加一些其他逻辑代码
12 继承write()和create()
重写write()和create(),在调用这个两个方法的前后编写一些用户权限认证代码
13 自定义记录的搜索方式
重写_name_search()方法
14 通过read_group()获取组中的数据
read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
read_group方法可以对数据使用聚合函数并且可以分组处理。
七 模块数据
1 使用外部ID和命名空间
XML ID的引用
xml中使用ref = 'model.xml_id’去引用对应的record标签记录对象
py中使用ref(‘model.xml_id’)去获取xml中的对应id值为xml_id的标签对象。
如果一个模块的xml文件中的record标签里的id值为"a.b",那么该record标签中的值则会覆盖a模块中的record标签id为b的记录。
2 使用XML文件加载数据
使用record标签并指定id和model属性值去预加载数据。
对于普通字段添加数据,直接在field标签中添加所需的值即可。
对于Many2one字段,可以使用ref属性指向其他模块的XML ID或者自身模块的XML ID。
对于xx2Many字段,使用eval属性去添加值
3 使用noupdate和forcecreate标记
noupdate=‘x’,x=1表示更新时不会修改,x=0表示更新时会修改。
forcecreate=‘y’,y=false表示不会重建,y=‘true’表示会重建。
用例:
xxx
xxx
可以在运行Odoo服务时带上-init=your_addon或-i your_addon参数去强制Odoo重载记录以及重建已删除的记录,这一代码可以绕过任意的noupdate标记。
4 使用CSV文件加载数据
使用csv文件添加访问控制列表(ACL)
5 插件更新和数据迁移
对插件的字段类型进行更新以及相应的数据迁移。
6 从XML文件中删除记录
在XML中有两种方式去删除记录:
1 通过指定XML ID:
2 通过搜索域:
注意:在Odoo很少使用,因为它很危险。
7 从XML文件中调用函数
在XML中可以使用button的name属性调用model中定义的方法
也可以使用function标签去调用model中定义的方法
扩展知识:
1 因为每次安装/升级对应模块时,都会执行这个标签,所以可以添加noupdate=‘1’
2 通过<function>
标签可以向函数发送参数。
用例:
# xxx.py
@api.model
def update_book_price(self, category, amount_to_increase):
category_books = self.search([('category_id' '=', category.id)])
for book in category_books:
book.cost_price += amout_to_increase
# xxx.xml
<function model='library.book' name='update_book_price' eval='(ref('category_xml_id', 20))'/>
八 调试
1 自动加载和–dev 选项
使用watchdog库
pip3 install watchdog
–dev=reload,qweb,werkzeug,xml,pudb|wdb|ipdb|pdb,all
2 产生服务日志来帮助调试方法
3 使用Odoo shell来交互调用方法
4 使用Python调试器来追踪方法执行
5 使用Odoo社区联盟维护者质量工具
6 理解调试模式选项