本文为最好用的免费ERP系统Odoo 12开发手册系列文章第一篇。
Odoo提供了一个快速应用开发框架,非常适合创建商业应用。这类应用通常用于保留业务记录,增删改查操作。Odoo 不仅简化了这类应用的创建,还提供了看板、日历、图表等视图的丰富组件,用于创建好看的用户界面。
本文主要内容有:
- 引入本文使用的学习项目:to-do (任务清单)应用
- 理解 Odoo 的结构、版本和发布,了解使用 Odoo 的相关知识
- 准备一个 Odoo 的基本工作环境,有如下选项:
- 在线Odoo
- Windows 一键安装包
- Docker
- 激活开发者模式,在用户界面中展示所需使用的工具
- 修改已有模型,添加字段,常用自定义快速入门
- 创建自定义数据模型,为我们的应用添加新的数据结构
- 配置权限,让指定用户组访问应用的功能
- 创建菜单项,在用户界面中展示新的数据模型
- 创建用户界面的基本组件:列表、表单、搜索视图
引入 to-do 列表应用
TodoMVC 项目提供一个多 JavaScript 框架实现的 to-do 简单应用类比。下面我们就用 Odoo 来创建一个简单的 to-do 应用。
使用这个应用我们可以添加新的 to-do 项,然后标记完成。比如可在项目中添加买鸡蛋,然后在购买后勾选已完成。To-do 项目应仅对当前用户可见,因而每个人可以获取自己的 to-do 列表。对于一个简易 to-do 应用这已足够,但为增加点趣味性,我们还将允许 to-do 列表项目包含一组和任务相关的用户,即工作小组。
就该应用我们应考虑以下几层:
- 数据层:通过模型实现
- 逻辑层:通过自动化编码实现
- 展示层:通过视图实现
对于数据层,我们需要一个 To-do 项目模型,我们还将利用内置的 partner(或 contacts)模型来支持工作组的功能。当然还要记得在新的模型中配置访问权限。
逻辑层中我们使用框架处理增删改查(CRUD)基本操作,要使用框架的功能,我们需要在开发者模块中使用 Python 代码。对于初学者,可以使用用户界面开发者菜单自动化工具来实现业务逻辑,后面的例子中会进行说明。
展示层中我们将为应用添加菜单项,以及 to-do 模型的视图。业务应用的基本视图是用于查看已有记录的列表视图、深入查看记录细节的表单视图。为增强易用性,我们还可以在列表视图中的搜索框预置过滤项。可用搜索选项也被视为一个视图,因而通过搜索视图可进行实现。
以下是创建 to-do 列表应用的步骤
- 创建 to-do 项的新模型,然后添加菜单让其可见
- 为 to-do 项模型创建列表和表单视图,新模型包含如下字段
- Description: text 类型
- Is Done?标记:布尔型
应用的具体功能包含添加执行同一任务的一组用户,因此需要一个表示用户的模型。所幸 Odoo 自带就有这样的模型 – partner 模型(res.partner),它可用于存储个人、公司和地址。并且仅有指定的人可被选择加入工作团队,因此我们需要修改 partner 模型添加Is Work Team?标记。
所以,任务清单模型还应包含一个工作团队字段,包含一组用户。在添加了Is Work Team?标记后这些关联用户可在 partners/contacts 中进行选取。
综上,我们需要做的有:
- 为 partner 模型和表单视图添加字段
- 创建一个 to-do 项模型
- 创建一个 to-do 应用菜单项
- 创建 to-do 项用户界面:列表、表单视图以及 UI 中的搜索选项
- 创建访问权限:组、权限控制列表(ACL)和记录规则
在落地实现之前,我们先要讨论下 Odoo 框架的基本概念,然后学习如何准备工作环境。
基本概念
理解 Odoo 结构中的各个层以及我们要使用的各类型组件的作用大有裨益。下面我们先总览下 Odoo 应用结构,然后把应用开发解构为对应组件。
然后 Odoo 发布有两个版本的定期更新:社区版和企业版,我们应了解两者之前的差别以及大版本发布对开发和部署所带来的变化。首先来看看 Odoo 的应用结构:
Odoo 结构
Odoo 遵循多层结构,即前述的数据层、逻辑层和展示层:
数据层是最底端一层,负责数据持久化存储,Odoo 借助 PostgreSQL来实现。Odoo 出于设计考虑仅支持 PostgreSQL 数据库,而不支持MySQL 这一类数据库(有第三方应用可集成 MySQL)。文件附件、图片一类的二进制文件通常存储在一个称为 filestore(目录) 的文件系统中。
小贴士:也就是说 Odoo 实例的完整备份需包含数据库和 filestore 的拷贝。
逻辑层负责与数据层的所有交互,并由 Odoo 服务完成。通常,底端数据库不应通过这一层获取,只有这样才能保证权限控制和数据一致性。在 Odoo的核心代码中包含供这一接口使用的 ORM (对象关系映射Object-relational Mapping)引擎。ORM 提供插件模块与数据交互的 API。
比如像客户和供应商这样的 partner 数据实体,是通过模型的 ORM 体现的。这一模型是一个 Python 对象,支持多种交互方法:create()方法用于创建新的伙伴记录,read()方法用于查询已有记录和对应数据。通用方法可在特定模型中实现指定业务逻辑,如 create()方法可以设置默认值或强化验证规则,read()方法可支持一些自动计算字段或根据执行操作的用户来实施权限控制。
展示层用于展示数据并与用户交互,通过客户端实现用户体验。客户端与 ORM API 交互来读、写、验证或执行其它操作,通过 RPC 调用 ORM API 方法。这些操作发往 Odoo 服务器端操作,然后结果发送回客户端做进一步处理。
对于展示层,Odoo 自带全面功能的 web 客户端。该客户端支持所有业务应用所需功能:登录会话、导航菜单、数据列表、表单等等。全局展示不会像前端工程师所认为的那样可深度定制,但易于创建功能性和连贯的用户体验。配套的展示层包含网站框架,可像其它 CMS 框架一样灵活地创建网页,当然需要额外的操作和 web 相关知识。网站框架支持通过 web 控制器实现代码来展示特定逻辑,而与模型内在逻辑进行区隔。前端工程师不会有什么操作上的障碍。
Odoo 服务端 API 非常开放,包含所有服务端功能。Web 客户端使用的 API 与其它应用的 API 并无不同。因此,其它的客户端实现均可做到,并且可以在任何平台上使用任意编程语言进行实现。可以创建桌面和移动端应用来提供不同用户界面,这充分利用了 Odoo 为业务逻辑和数据持久性而生的数据和逻辑层。
Odoo社区版 vs. 企业版
Odoo 是这款软件的名称,同时也是发布软件的公司名称。Odoo 采取核心开源的业务模式,社区版(CE)完全免费开源,而企业版(EE)则是一款付费产品。社区版提供了全部的框架功能和大多数与 Odoo 捆绑的业务应用基础功能。Odoo 采取 LGPL 开源协议,允许在开源模块之上添加专属扩展。企业版建立在社区版基础之上,包含社区版所有功能和额外的独有功能。值得一提的是企业版带有一个移动端优化的用户界面,两个版本的用户界面底层完全相同。Odoo 在线 SaaS 服务使用的是企业版,会部署一些企业版大版本发布之后的中间版本。
Odoo 的版本政策
在写本文时,Odoo 的稳定版本号是12,在 GitHub 上的分支为12.0,这也是本系列文章所采用的版本。近年来 Odoo 的大版本都是按年发布, Odoo 12是在2018年10月份的 Odoo 体验大会上发布的。官方支持最近的三个稳定版本,在12.0发布时,官方仍然维护11.0和10.0两个版本,而停止对9.0的支持,也就是不再对 bug和安全漏洞进行修复。
应当注意 Odoo 不同大版本间的数据库并不兼容,比如在 Odoo 11服务端运行早前版本的 Odoo 数据库,系统将无法运行。在不同版本间迁移数据库也颇费周折。对于插件模块也是如此,通常老版本中开发的插件无法在新版本中生效,所以在网上下载社区模块时,应注意选择对应的版本。
此外,大版本(如10.0, 11.0)会被频繁的更新,但这些通常仅仅是 bug 的修复。这些修复会确保 API 稳定,也就是模型数据结构和视图元素标识符也会保持稳定。这点非常重要,因为这意味着我们的自定义模块不会因上游核心模块的不兼容修改而崩溃。
Master 分支中的版本将产生下一个稳定的大版本,但在形成稳定版之前,将不会保持 API 稳定,我们应避免使用它来创建自定义模块。否则会如同在流沙中行进般不确定,我们无法保证什么改变会导致自定义模块的崩溃。
基本工作环境的准备
首先我们需要一个 Odoo 实例来进行学习,本文仅要求运行一个 Odoo 实例,与具体的安装方法无关。想要快速运行,我们可以使用一个预打包的 Odoo 发布,甚或是使用 Odoo SaaS 的试用版本。
使用 Odoo SaaS试用版本
这是最为简便的方法,无需进行任何安装,仅需进入官网创建一个试用数据库。这一 Odoo 云端软件是基于企业版的 SaaS 服务,采用独有的中间版本发布。在写本文时,这一服务不仅支持试用,在仅安装一个应用的情况下可以免费使用。SaaS 服务使用原生的 Odoo 企业版,不支持自定义模块。在需要进行自定义时,可使用 Odoo.sh 服务,它提供一个可自定义全面功能的开发平台和主机托管方案。
注意:在 Odoo 早前版本中,社区版和企业版的菜单结构有相当大的差别,而 Odoo 12中,两者之间的结构相近。
在 Odoo 云端 SaaS 创建新数据库,会需要选择一个应用,针对本文可选择任意应用。对于有选择尴尬症的朋友,可以使用CRM 客户关系管理应用。另外值得一提的是在 Odoo SaaS企业版中可选择 Odoo Studio 应用构建器,因本系列所针对的社区版并不包含,所以我们不会用到。Odoo Studio 为开发者提供了一个用户友好的使用界面,还有一些其它功能,如导出在模块包中所做自定义修改。但其主要功能都可在开发者模式中获取。
在 Windows 上安装 Odoo
一键安装包可以在Odoo官网上下载,包含各个版本及主分支,这里有 Windows 安装包(.exe)、Debian 安装包(.deb)和 CentOS 安装包(.rpm)。要在 Windows 上安装,仅需在对应版本的 nightly 文件夹中找到.exe 并进行安装。安装包非常方便,它包含安装 Odoo 所需的所有部分:Python 3、PostgreSQL 数据库、Odoo 服务端以及其它 Odoo 依赖。安装时会创建一个 Windows 服务在开机时自动启动 Odoo 和 PostgreSQL。
使用 Docker 容器安装 Odoo
Docker是一个快捷运行应用的跨平台解决方案,在 MacOS, Linux 和 Windows 上均可使用。与传统的虚拟机相比,容器技术使用更为简单、资源利用率更高。首先需要在操作系统中安装 Docker,可从Docker官网上下载免费使用的Docker CE(社区版),最新安装方法可在 Docker官网上查看。
应该注意虚拟化要求在 BIOS配置中进行开启,并且 Windows 版本的 Docker CE 需要有 Hyper-V,它仅在 Windows 10 企业版或教育版才会带有(Windows 系统要求),而 Mac系统需要为 OS X El Capitan 10.11或更新版本。对于其它的 Windows 和 MacOS 版本,应安装 Docker Toolbox,Docker Toolbox打包了 VirtualBox 并提供了预设置的 shell,用于作为操作 Docker 容器的命令运行环境。
译者注:想要深入学习 Docker的朋友可参见 Alan 所翻译的另一套书:【已完结】精通 Docker 第三版中文版
在 Odoo 商店中包含 Odoo 镜像,在那里找到对应版本,按照提示进行安装。要使用 Docker运行 Odoo,我们需要两个容器,一个运行 PostgreSQL 数据库,一个运行 Odoo 服务。
安装通过命令行窗口完成,安装 PostgreSQL 容器
1 |
docker run -d -e POSTGRES_USER=odoo -e POSTGRES_PASSWORD=odoo -e POSTGRES_DB=postgres --name db postgres:10 |
此时便会从互联网上下载最新的 PostgreSQL 镜像,并在后台开启一个容器来进行运行。
接下来安装 Odoo 服务容器,并且连接刚刚启动的 PostgreSQL 容器,在本地暴露8069端口:
1 |
docker run -p 8069:8069 --name odoo --link db:db -t odoo |
此时便可在终端窗口看到实时的 Odoo 服务器日志,在浏览器中输入http://localhost:8069即可打开 Odoo 实例。
小贴士:如果8069端口被占用了,则Odoo 服务启动会失败。此时我们需要停止占用该端口的服务或者使用-p 参数指定其它端口来运行 Odoo,如修改为8070端口(-p 8070:8069)。此时可能还需要通过-d 参数修改实例所需使用的数据库名称。
以下Docker 的基本指令会有助于管理容器:
- docker stop <name> 停止指定容器
- docker start <name> 启动指定容器
- docker start -a <name> 启动容器并附带输出,如命令终端中输出的服务器日志
- docker attach <name> 重新添加容器输出至当前终端窗口
- docker ps 列出当前 Docker 容器
以上就是操作 Docker 容器的基本命令,万一在运行容器时出现问题,可以执行如下命令(可省略 container)重新来过:
1 2 3 4 |
docker container stop db docker container rm db docker container stop odoo docker container rm odoo |
Docker 技术的应用非常广泛,更多知识可参见 Docker 官方文档。
其它安装选项
Odoo也有 Linux 系统的安装包,包含 Debian 系(如 Ubuntu)和 Red Hat 系(如 CentOS和 Fedora)。官方文档中有相关说明,也可参考:
对于源码安装会相对复杂,但可变性也更强,在第二章 Odoo 12开发之开发环境准备中还会详细介绍。
创建工作数据库
通过前面的学习,我们应该都有一个 PostgreSQL 数据库和 Odoo 服务器供运行了。在开始使用我们的项目前还需要再创建一个 Odoo 数据库。如果您在本地安装 Odoo 并保留了默认设置,则可以通过http://localhost:8069/打开 Odoo。第一次打开时,还没有可用的数据库,此时可以看到一个用于创建数据库的页面:
创建数据库需的信息有:
- Database Name:数据库的标识名称,在同一台服务器上可以有多个数据库
- Email:管理员的登录用户名,可以不是 email 地址
- Password:管理员登录的密码
- Language:数据库的默认语言
- Country:数据库中公司数据所使用的国家,这个是可选项,与发票和财务等带有本地化特征的应用中会用到
- Demo data:勾选此选项会在数据库中创建演示数据,通常在开发和测试环境中可以勾选
如果在 Odoo 的服务端配置中添加了 master password,还会要求输入该密码。这可以阻止未经授权的用户执行相关管理员操作,默认情况下不会设置该密码。 点击 Create database 按钮后,会开始初始化数据库,整个过程可能会需要一到几分钟,结束后会自动登入后台。
登录界面底部有一个 Manage Databases 的链接,点击进入会可以看到当前可用的数据库,可对它们进行备份、复制和删除操作,当然还可以创建新的数据库。直接进入的地址为:http://localhost:8069/web/database/manager
小贴士:数据库管理器可进行一些管理操作,默认开启且没有保护措施。虽然对于开发来说这样非常方便,但即便是在测试或开发环境,对包含有真实数据的数据库都存在安全风险。建议设置一个复杂的管理密码甚至最好是关闭这一功能(在配置文件中设置 list_db = False)。
现在我们已有经了 Odoo 实例和数据库,下一步就是开启开发者模式这个用于实现我们项目的工具。
开启开发者模式
要实现我们的项目,这里需要用到开发者模式所提供的工具。开发者模式使我们可以在用户界面中直接对 Odoo 应用进行自定义操作。这有利于我们快速修改和添加功能,可用于进行一些添加字段的小调整乃至像创建带有多个模型、视图和菜单项的应用这样的复杂自定义开发。
但这种直接在用户界面执行的自定义开发相对于在后续章节讲到的编程工具而言也有其局限性,如它无法添加或扩展默认的 ORM 方法(虽然有时自动化动作足以作为一个替代方案)。它也不易于集成到结构性开发流,如版本控制、自动化测试、部署到多环境(质量测试、预发布和生产环境)。
本文我们主要使用开发者模式来介绍在 Odoo 框架中应用配置是如何组织的、如何在开发者模式下进行简单的自定义和快速列出所要实现方案的框架或原型。进入 Settings > Dashboard, 即可在右侧下方看到Activate the developer mode链接,点击该链接即可开启开发者模式(Odoo 9.0版本及其以前的版本,开发者模式在 User 菜单的 About 对话框窗口中进行开启)。
在该页面我们还会看到一个Activate the developer mode (with assets)的选项,这个用于不对静态文件进行压缩,通常用于调试前端代码,开启后浏览的速度也会略慢。为加快加载速度,客户端中的 JavaScript 和 CSS 文件通常会被压缩。但这也导致我们很难对前端代码进行调试,Activate the developer mode (with assets)选项会把这些静态文件按照独立文件、非压缩的方式进行加载。
我们也可以通过修改当前的 URL 来进入开发者模式,这样就无需进入 Settings 页面,仅需修改链接中的…/web#…为…/web?debug#…或…/web?debug=assets#…,比如修改http:///localhost:8069/web#home为http://localhost_8069/web?debug#home。虽然没有直接的链接来开启前端框架的开发者模式,但也可以通过在前端页面URL上添加?debug=assets 来取消静态文件的压缩, 但需要注意在我们进入其它页面时这个标记可能就会消失。
小贴士:Firefox 和 Chrome均提供开启和取消开发者模式的插件,请在火狐或 Chrome 的应用商店中搜索 Odoo debug 进行安装
开发者模式一经开启,在菜单中就会增加两个选项:
- 开发者工具菜单,以调试图标的形式出现在右上角用户名和头像的左侧
- Settings 中的 Technical 菜单项
开发者模式还会在表单字段上添加一个额外信息:将鼠标悬停在字段上方,就会显示一些相关技术信息。下一部分我们一起来学习相关的开发者模式功能。
为已有模型添加字段
为已有表单添加字段是种常见的自定义操作,我们无需创建自定义模块即可在用户界面中进行实现。就我们 To-do 应用而言,需要可以选取一组用户对 To-do 项进行协作。我们可以通过在 partner 表单中添加标识来找到这些用户,那么接下来为 partner 模型添加一个Is Work Team?标记。
Partner 模型是 Odoo 内核自带的,无需安装任何应用即可使用,但这样在菜单中会无法查看到。一个简单的方法是安装 Contacts 应用。没安装的朋友可以点击 Apps 菜单搜索该应用并进行安装:
安装完成后即可在顶级菜单中找到 Contacts 项。
为模型添加字段
开启开发者模式后,我们可通过菜单Settings > Technical > Database Structure > Models 来查看模型的定义。这时搜索 res.partner(未安装其它应用的情况下第一个即是),对应的模型描述为 Contact。点击打开表单视图,这时就可以看到 partner 模型的各类信息,包含字段列表:
点击 Edit,然后在字段列表的最下端点击 Add a line,即会弹出窗口用于创建新字段,输入:
- Field Name: x_is_work_team
- Field Label: Is Work Team?
- Field Type: boolean
字段名(Field Name)必须以 x_开头,这是在用户界面创建模型和字段强制要求的(否则保存时会提示Custom fields must have a name that starts with ‘x_’ !),通过插件模块的自定义开发不受这一限制。只修改添加以上信息点击Save & Close保存即可。 这个模型有80多个字段(如未安装 Contacts 仅50多个字段),我们需要通过右上角的向右箭头浏览到最后一页才能看到新创建的字段。这时再点击左上角的 Save 按钮进行最终的保存。
为表单视图添加字段
我们已经为 partner 模型创建了新字段,但对用户仍不可见,要实现这点我们还要在相应的视图中进行添加操作。再回到前述的 res.partner模型详情页,点击 Views 标签,我们就可以看到模块的各个 view 定义。正如所见,每个视图都是一条数据库记录,修改或添加视图记录即时生效,在下一次加载视图时即可见:
视图列表中有一些需要注意的事项,我们看到有不同的视图类型(View Type),如表单视图(Form)、树状列表视图(Tree)、搜索视图(Search)和看板视图(Kanban)。搜索视图指的是右上角搜索框中的过滤选项。其它视图的数据展示方法也各不相同,基本的类型有列表视图和表单视图(用于查看详细信息)。
小贴士:树状视图(Tree) 和 列表视图(List) 实为同一视图,实际上Odoo 中的为列表视图,树状视图的名称是由历史原因产生的 – 过去列表视图是以树状层级结构来进行展示的。
可以看到同一视图类型存在多个定义,通过 View Type 进行排序可以更清晰地看出。每种视图类型(如表单视图)可以有一个或多个base视图定义(包含空的继承视图字段)。菜单项使用窗口动作(Window Action)可以指定要用到的base视图,如果没有定义,将使用排序值(Sequence)最低的,因而可将其视为默认视图。 点击视图,可以在表单中看到包含排序值在内的所有详情:
每个base视图都可以有多个扩展,称为继承视图。每个继承视图可以对base视图添加修改,如对已有表单添加字段。
小贴士:继承视图自身也可以被其它视图继承,这时最外层继承在内层继承执行后作用于base视图。
res.partner 模型会包含众多的视图定义,因为类似我们的很多应用都需要对其进行扩展。一个替代方法是进入我们需要扩展的某一具体视图,使用开发者工具菜单对其进行编辑。这也可用于了解某一视图在用户界面的某处被使用了。下面我们就来进行操作:
1.点击 Contacts 应用显示联系人名片列表,然后点击任意名片进入相应的表单视图
2.在表单视图界面,点击开发者工具菜单(右上角调试图标)并选择编辑视图(Edit View:Form),这时可以看到与前述模型页面相同的视图详情表单,但展示在实际定义使用base视图之上。也就是res.partner.form视图,通过External ID可以查看模块所有者。本处为base.view_partner_form,所以我们知道这个视图属于base模块。在Architecture字段中,我们可以看到base视图定义的 XML 代码。我们可以在这里编辑视图结构并添加我们的新字段,但从长期看这不是一个好办法:这个视图属于一个插件模块,一旦模块被更新,自定义的代码就会被覆盖并丢失。修改视图的正确姿势为创建一个继承视图(Inherited Views)扩展:
3.使用继承视图标签我们可以为 base 视图添加扩展视图:
I.首先我们需要在原始视图选择一个元素作为扩展点,我们可以通过查看 base视图的结构选择一个包含 name 属性的 XML 元素,大多数情况选择的是一个<field>元素,此处我们选择<field name=”category_id”…>元素:
II.现在,点击开发者工具菜单,然后点击编辑视图(Edit View:Form),选择继承视图(Inherited Views)标签回到前述的界面,然后点击最下方的 Add a line链接
III.此时会弹出名为Create Views which inherit from this one的窗口,填入如下内容
- View Name: Contacts – Custom “Is Work Team” flag
- Architecture:输入如下 XML代码
1 2 3 |
<field name="category_id" position="after"> <field name="x_is_work_team" /> </field> |
- 其它重要字段,如 Model, View Type 和 Inherited View 使用默认值即可
IV.此时点击 Save & Close按钮,然后在Edit View: Form 窗口点击Save按钮
在保存修改后重载联系人表单视图页面即可查看到变化,在大数浏览器中可以使用 F5快捷键来重载页面。这时打开任意联系人名片,可以看到右侧 Tags 字段下会多出一个新字段:
创建新的模型(Model)
模型是应用的基本组件,包含了所需使用到的数据结构和存储。接下来我们就为 To-do 项目添加模型,将包含三个字段:
- Description
- Is done? 标记
- Work team 用户列表
如前所述,通过菜单Settings > Technical > Database Structure > Models可进入模型创建页面,步骤如下:
1、进入模型菜单,点击左上角 Create 按钮,在弹出页面填入
- Model Description: To-do Item
- Model: x_todo_item
在进一步添加字段之前可以先进行保存。
2、点击 Save 保存然后点击 Edit 再次进入编辑,可以看到 Odoo 自动添加了一些字段,ORM在所有模型中添加了这些字段,可用于审计和记录功能。
x_name (或Name)字段是在列表中显示记录或其它记录中引用时显示的标题。在 To-do Item标题中将使用它,还可以对其进行编辑将字段标签改为更能表达含义的描述。基于前面的知识添加 Is Done? 标记此时就显得非常容易了。
3、在字段列表页底部点击 Add a line 链接创建一个包含如下值的字段:
- Field Name: x_is_done
- Field Label: Is Done?
- Field Type: boolean
该字段的填写效果如下:
接下来添加 Work Team 字段就带有挑战性了,不仅因为这是一个指向 res.partner 对应记录的关联字段,它还是一个包含多个值的 selection 字段。在很多框架中这都会颇为复杂,但所幸我们使用的是 Odoo,因为它支持 many-to-many 关联。任务清单应用属于这一情况,因为一条任务可以有多个用户,同时一个用户也可以参与多个任务。
4、再次在字段列表中点击 Add a line,添加一个包含如下值的字段:
- Field Name: x_work_team_ids
- Field Label: Work Team
- Field Type: many2many
- Object Relation: res.partner
- Domain: [(‘x_is_work_team’, ‘=’, True)]
many-to-many字段有其独有的定义项-Relation Table, Column 1, and Column 2项,这些值会被自动填充,大多数情况下都无需修改。在第六章 模型 – 结构化应用数据中将会有更详细的探讨。 Domain 项为非必填项,这里使用到是因为只有符合条件的用户才可被选取加入工作组,如果不加这项则所有用户均可被选取。
Domain 表达式中对展示的记录进行了过滤,它遵循Odoo 独有的语法 – 一个包含三个值的元组(补充:经测试使用列表也同样可以),第一项为待过滤的字段名、第二项为过滤操作符、第三项为过滤作用的值。详细的解释参见第七章 记录集 – 使用模型数据。
小贴士:Odoo有一个交互式的 domain 过滤向导可帮助生成 domain 表达式。访问Settings > Technical > User Interface > User-defined Filters,点击 Create选择模型后将会出现 Add filter 按钮,可通过选择字段在下方的文本框中实时生成 domain 表达式。
现在我们已经为 To-do应用创建好了模型,但还无法使用它,在创建模型后,我们需要配置组来使用该模型。
配置安全权限控制
Odoo自带有权限控制机制,用户仅能使用被授权了的功能。这就意味着我们自建的库功能不对普通用户甚至是管理员开放。
注意:Odoo 12的修改
管理员用户现在也像其它用户一样受权限控制所限制。在此前的 Odoo 版本中,admin 都作为特权用户不受权限规则控制。而新版中我们需要进行授权管理员才能访问模型数据
Odoo 安全权限通过安全组来设置访问权限。每个用户的权限根据所属组来决定,对于我们的测试项目,我们将创建一个 to-do 用户组,然后通过组来分配可使用功能的用户。我们通常使用 ACL 为某个组赋予指定模块的读或写权限,就当前项目,我们对添加的 to-do 项模型添加读和写权限。
此外,我们还可以设置用户对指定模型的记录范围的访问规则。本项目中 to-do 项为用户私有,所以用户仅能访问自己创建的记录,这通过安全记录规则实现。
安全组
访问控制基于组,通过安全组对模型设置权限,控制组内用户所能使用的菜单项。要做更精细化的控制,我们可以对指定菜单项、视图、字段甚至是(带有记录规则的)数据记录进行权限控制。
安全组还可以对应用进行管理,通常每个应用有两个组:用户组(Users)可执行日常操作、管理员组(Manager)可对应用执行所有配置。
下面我们新建一个安全组,在菜单中访问Settings > Users & Companies > Groups。点击 Create通过如下值创建一条新记录:
- Application: 留空
- Name: To-do User
- Inherited 标签下: 添加User types / Internal User项
效果如下:
在 Application 下拉列表中还没有to-do 应用,所以我们直接通过组表单来添加。我们还继承了 Internal User 用户组,那么这个组的成员也会自动(递归)成为所继承组的成员,以获取他们原有的权限。Internal User 是基础权限组,通常应用的安全组都继承它。
注意:Odoo 12的修改
在 Odoo 12之前,内部用户组称作雇员(Employee),这只是表面上的修改,代码中标识符(XML id)仍然和此前版本相同:base.group_user。
安全权限控制列表
现在我们可以对指定组(To-do User)进行指定模型的权限授予,在上述表单的Access Rights标签下添加一条记录,对应的值为:
- Name: To-do Item User Access
- Object: 在列表中选择To-do Item
- 勾选Read Access, Write Access, Create Access, and Delete Access
模型权限也可通过Settings > Technical > Security > Access Rights进行管理。我们无需向 Partner 模型添加权限,因为我们的组继承了内部用户组,已经获取了相应权限。
现在可以将 admin 用户添加到新建组来测试新加的权限设置
1、在菜单中点击Users & Companies > Users,从用户列表中选择Mitchell Admin,然后编辑表单
2、在Access Rights标签下的 Other 版块,会发现一个名为 To-do User 的复选框用于让用户加入权限组,勾选后点击 Save 保存表单。
如果一切操作都正确的话,我们就可以看到 To-do 顶级菜单,用于添加任务清单项,并且我们只能访问自己的任务清单而看不到其它人的。(请先执行创建菜单项部分再进行查看)
安全记录规则
在对模型赋予访问权限时,默认用户可以访问到他的所有记录。但有时我们要限制每个用户所能访问的特定记录。通过记录规则可以实现这一点,通过定义 domain 过滤器来对读和写操作进行控制。
比如我们这里的 to-do 应用,任务项应为用户私有,我们不希望其他用户看到自己的记录。需要添加记录规则来过滤出创建者自己的记录:
- 框架会自动添加create_uid字段,并存储创建记录的用户,通过该字段可以确定每条记录的创建者
- 在user变量中可获取到当前用户,user 变量读取上下文中 domain 过滤器过滤后的对象
通过[(‘create_uid’, ‘=’, user.id)]域表达式可实现这点。通过菜单中的Settings > Technical > Security > Record Rules 进入记录规则设置页,点击 Create 并输入如下值:
- Name: 一个描述性的标题,这里使用 To-do Own Items
- Object: 在列表中选择模型,此处为To-do Item
- Access Rights: 规则所授予的操作,这里保留全部勾选
- Rule Definition: 域过滤器,填写 [(‘create_uid’, ‘=’, user.id)]
- Groups: 作用的安全组,选择To-do User组
效果如下:
此时就完成了记录规则的设定,现在可以试试用 Admin 和 Demo 用户(需提前将 Demo 用户加入到安全组)分别创建几个任务项,各自将只能看到自己创建的任务。记录规则可通过右上角的切换按钮进行关闭,一旦关闭,用户就可以看到所有人的任务清单了。
超级用户账号
在此前的 Odoo 版本中,admin 用户是一个特权用户可以不受权限控制。Odoo 12就此做了调整,admin 用户属于所有用户安全组,但只是个普通用户。还是存在一个超级用户不受权限控制,但它无法直接登录。
我们还是能以超级用户进行操作,当一个用户以 Administration / Settings 用户组登录时,开发者工具菜单中有一个 Become Superuser选项,或者在登录页面开启开发者模式,则会出一个Login as superuser的隐藏按钮。
在激活了超级用户后,右上角的当前用户显示为 OdooBot,该处背景也会变成黄黑间隔的条状,以清晰地告知用户激活了超级用户。仅在绝对必要时才应使用这一操作,超级用户不受权限控制这点会导致数据的不一致,比如在多公司场景下,所以应尽量避免。
创建菜单项
现在有了存储任务清单的模型,应在用户界面中显示它,添加菜单项可实现这一点。我们这里创建一个顶级菜单项直接打开任务清单,一些像联系人(Contacts)这样的应用采取了这种方式,但另外一些则使用了在顶栏中的子菜单项。
注意:Odoo 12的修改
社区版中第一级以下的菜单项也像企业版中一样显示在了顶栏中,而此前版本社区版的菜单项显示在屏幕的左侧。
点击菜单Settings > Technical > User Interface > Menu Items,点击 Create 即可进入菜单的编辑页面。在该页面中输入如下值:
- Menu: To-do
- Parent Menu: 留空
- Action: 选择ir.actions.act_window,然后在右侧下拉框中点击Create and Edit打开一个相关的窗口操作表单
- 在弹出的表单中填入
- Action name: To-do Items
- Object: x_todo_item (目标模型的编码标识)
- 显示效果如下
- 保存所有打开的表单,此时即可在菜单中使用 To-do 应用了
要在菜单中显示该项,需要重载客户端页面,大多数浏览中可使用快捷键 F5(强制刷新:Windows: Ctrl+F5, Mac: Cmd+F5)。现在就可以访问菜单项并进行任务清单模型的交互了。虽然我们没有创建视图,但强大的 Odoo 框架自动为我们生成了一个基础视图:
在本例中,在顶级菜单中直接添加了一个操作,而没有子菜单。但菜单可以包含一系列带有父子关系的菜单项,最末级菜单项关联一个动作(Action),定义有选取时执行的行为。 动作名将作为所展示视图的标题。
有很多的操作类型,最重要的有窗口(window)、报表(reports)和服务端(server)动作。窗口动作最常用,用作在客户端中展示视图,报表动作用于运行报表,服务端动作用于定义自动化任务。
截至目前,我们都聚焦在显示视图的窗口动作上,正是使用了直接在菜单项表单中创建的窗口操作来创建了任务清单的菜单项。我们也可以在Settings > Technical > Actions中查看和编辑动作,在本例中仅需使用窗口操作。
小贴士:很多情况下使用开发者工具中的 Edit Action 选项更为方便,它提供一个编辑当前视图窗口操作的快捷方式。
接下来我们进入到下一部分,创建我们的视图。
创建视图
前面我们创建了一个任务清单模型通过菜单项在用户界面中显示,接下来我们为它创建两个基本视图:列表视图和表单视图。
列表视图
创建列表视图步骤如下:
1、点击Settings > Technical > User Interface > Views,点击 Create 进入视图编辑页面,填入如下值:
- View Name: To-do List View
- View Type: Tree
- Model: x_todo_item
效果如下:
2、在Architecture标签下,使用 XML 书写视图的结构,代码如下:
1 2 3 4 |
<tree> <field name="x_name" /> <field name="x_is_done" /> </tree> |
列表视图的基本结构非常简单:一个包含列表视图中显示的一个或多个数据列的元素(element)。在列表视图还有一些有意思的选项,将在第十章 后台视图 – 设计用户界面中详细探讨。
表单视图
创建表单视图的步骤如下:
1、创建另一条视图记录,并填入如下值:
- View Name: To-do Form View
- View Type: Form
- Model: x_todo_item
小贴士:如果不指定 View Type,将会通过视图定义代码来自动识别。
2、在Architecture标签下, 输入如下XML 代码:
1 2 3 4 5 6 7 8 9 |
<form> <group> <field name="x_name" /> <field name="x_is_done" /> <field name="x_work_team_ids" widget="many2many_tags" context="{'default_x_is_work_team': True}" /> </group> </form> |
表单视图结构根节点有一个<form>元素,包含<field>元素,其它相关元素将在第十章 后台视图 – 设计用户界面中进行学习。这里还有一个针对工具组字段的小组件(widget),以标签按钮而非列表栏显示。这一个按钮状标签通过在工作组字段中添加 widget 属性来实现。
默认情况下,关联字段允许直接创建记录用作关联。也就说可以在工作组字段中直接创建用户,但如果这么做用户将不会带有Is Work Team? 标记,也就产生了不一致性。
搜索视图
我们可以为列表视图右上角的搜索框预设一些过滤项和分组选项,Odoo 把这也视为视图元素,所以可以像列表视图和表单视图一样在 Views 中添加记录来定义。想必现在大家已经非常熟悉了,在菜单中点击Settings > Technical > User Interface > Views 或在开发者工具中对应上下文中进行编辑操作均可。我们进入任务清单列表视图,点击开发者工具中的Edit Search View。
当前列表清单模型还未定义过任何搜索视图,所以显示一个空表单用于进行创建,填入如下值并保存:
- View Name:选择一个有意义的描述,此处使用To-do Items Filter
- View Type: Search
- Model: x_todo_item
- Architecture: 添加如下XML 代码:
12345<search><filter name="item_not_done"string="Not Done"domain="[('x_is_done', '=', False)]" /></search>
此时重载任务清单,可以在搜索框下方 Filters 按钮下选择预设的 Not Done 过滤器,在搜索框中输入 Not Done也会提示过滤条件。默认开启过滤器会较便捷,在不需要时取消过滤即可。正如默认字段值一样,还是使用 context 属性来设置默认过滤器。
在点击 To-do 菜单时,执行一个窗口操作打开列表视图,该操作可设置一个上下文值,让视图默认开启某一搜索过滤器,操作步骤如下:
- 点击To-do 菜单进入任务清单列表
- 点击开发者工具图标并选择Edit Action,这时将弹出一个窗口操作界面,在右下角有一个 Filters版块,这里有 Domain 和 Context 字段。
Domain 字段可用于为所显示记录设置固定的过滤器,而且用户无法删除。这不符合我们的场景。我们只是要默认开启item_not_done过滤器,用户可以随时取消选择。默认打开过滤器,添加以search_default_作为前缀的 context 键,这里使用{‘search_default_item_not_done’: True}
这时再点击 To-do 菜单,搜索框中默认就会开启 Not Done 过滤器。
总结
在本文中,我们不仅概览了 Odoo 组件的组织方式,还利用开发者模式深入到 Odoo 内部来理解这些组件如何共同协作创建应用。
我们还使用这些工具创建了一个简易的应用,包含模型、视图和对应的菜单。并且掌握了通过开发者工具可以查看当前应用或在用户界面中直接进行快速自定义操作。
下一篇中我们将更深入地了解 Odoo 开发,并学习如何设置和组织开发环境。
☞☞☞接下来请学习Odoo 12开发之开发环境准备
学霸专区
- 在设计 Odoo 应用时应考虑哪些相关层?
- 如何开启开发者模式?
- 在何处创建数据模型?
- 如何向终端用户开启数据模型让其创建和编辑记录?
- 在已有表单中如何添加字段?
- Domain 是什么?可以在何处使用?
- 如何为访问的表单设置默认值?
- 如何授权用户访问模型?
- 如何为任务清单添加分类字段,并可在列表中进行选择?(选项列表可由用户编辑和扩展)
- 如何继承任务清单分类模型,让特定分类仅适用于指定用户?