Alan Hou的个人博客

Odoo 13开发者文档:建造网站

Odoo中的任务通过创建模块来实现。

模块自定义Odoo安装软件的行为,要么通过新增行为,要么通过改变已有的行为(包含由其它模块所添加的行为)。

Odoo脚手架 可配置一个基本的模块。仅需调用如下命令来快速开启:

这会自动创建一个my-modules 模块目录,其中放置一个 academy 模块。这个目录可以是已有的模块目录,但模块名在目录内必须是唯一的。

现在我们已经有一个“完整的” 模块可供安装了。

虽然它还没有什么功能,但我们可以进行安装:

  • 启动Odoo服务
  • 访问 http://localhost:8069
  • 新建一个包含演示数据的数据库
  • 访问Settings ‣ Modules ‣ Modules
  • 在右上角移除Installed 过滤器并搜索 academy
  • 点击 Install按钮在安装 Academy 模块

控制器 解释浏览器请求并返回数据。

添加一个简单的控制器并确保它通过__init__.py 进行了导入(这样Odoo可以发现它):

academy/controllers.py

关闭服务(^C) 然后再重启:

打开页面 http://localhost:8069/academy/academy/,你应该可以看到自己的 “页面” 出现:

在Python中生成HTML并不友好。

通常的方案是 templates,带有占位符并展示逻辑的伪文档。Odoo允许使用任何Python 模板系统,但提供了它自己的 QWeb 模板系统,在其中集成了一些其它功能。

创建模板并确保模板文件在 __manifest__.py 声明文件中进行了注册,修改控制器来使用我们的模板:

academy/controllers.py

academy/templates.xml

模板遍历 (t-foreach) 所有的教师 (通过template 上下文进行传递),,并在单独的段落中分别打印都是。

最后重启Odoo并通过进入Settings ‣ Modules ‣ Modules ‣ Academy并点击Upgrade来更新模块的数据(来安装模板)。

访问 http://localhost:8069/academy/academy/ 应当会显示如下结果:

Odoo模型 映射数据表。

在前面的部分中我们只是展示Python代码中静态输入的字符串列表。这并不允许进行修改或持久化存储,因此现在我们需要将数据迁移到数据库中。

定义teacher模型,并确保其在 __init__.py 中进行了导入来正确加载:

academy/models.py

然后为模型设置 基本权限控制 并将其添加到声明文件中:

academy/__manifest__.py

academy/security/ir.model.access.csv

以上只是向所有用户 (group_id:id 留空).赋予了读权限 (perm_read) 。

第二步是要添加演示数据来方便测试。这通过添加 demo 数据文件来实现,它必须要在声明文件中进行添加:

academy/demo.xml

最后一步是修改模型和模板来使用我们自己的演示数据:

  1. 用数据库代替静态列表来获取记录
  2. 因 search() 返回一个匹配过滤器 (此处为“所有记录”)的记录集,修改模型来打印每个教师的 name

academy/controllers.py

academy/templates.xml

重启服务并更新模块(来更新声明文件和加载演示文件),然后访问http://localhost:8069/academy/academy/。页面会有一些不同:名词前有一个数字(教师的数据库标识符)。

Odoo打包了一个针对构造网站的模块。

到此我们都直接地使用了控制器,但Odoo 8通过website模块新增了更深入的集成以及一些其它服务(如默认样式、主题)。

  1. 首先将 website 添加为 academy的依赖
  2. 然后对控制器添加website=True 的标记,这对请求对象设置了一些新变量并且允许在我们的模板中使用网站布局
  3. 在模板中使用网站布局

academy/__manifest__.py

academy/controllers.py

academy/templates.xml

在重启服务更新模块后台后台 (来更新声明文件和模板),访问http://localhost:8069/academy/academy/ 应该会看到一个带有品牌编号内置页面元素的页面(顶级菜单、footer, …)

网站布局还提供对编辑工具的支持:点击右上角的Sign In,填写账号信息  (默认为admin / admin ) 然后点击Log In。

网站布局还提供对编辑工具的支持:点击右上角的Sign In,填写账号信息  (默认为admin / admin ) 然后点击Log In。

现在就进入了Odoo的 “地盘”: 管理界面。此时点击Website菜单项(在右上角)。

我们以管理员身份回到了网站,可以访问website所提供支持的高级编辑功能。

控制器方法通过 route()装饰器与路由进行关联, 装饰器接收一个路由字符串和一些用于自定义其行为或权限的属性。

我们看到了一个“字面量”路由字符串,与URL版块进行精准的匹配,但路由字符串也可以使用匹配URL位的 转换器模式 ,并将这些作为局部变量。例如我们可以新建一个控制器方法,其中接收URL 并将其打印出来:

academy/controllers.py

重启Odoo,访问 http://localhost:8069/academy/Alice/ 和 http://localhost:8069/academy/Bob/ ,查看区别。

如名称所示, 转换器模式 不只是进行提取,还可以进行 验证 和 转换,,这样我可以修改新控制器来仅接收整型:academy/controllers.py

重启Odoo,访问 http://localhost:8069/academy/2,注意如何将老的字符串值转换为整型的。试着访问 http://localhost:8069/academy/Carol/ 并注意页面是找不到的:因为“Carol” 不是个整型,路由被忽略而找不到路由。

Odoo 提供一个额外的转换器,名为 model ,直接在给出它们的 id 时提供记录。我们来使用它创建一个针对教师简介的通用页面:

academy/controllers.py

academy/templates.xml

然后修改模型列表来关联到我们的新控制器:

academy/templates.xml

重启Odoo并升级模块,然后你可以访问每个教师的页面。作为练习,在教师的页面中添加代码码来写入简介,然后进入其他教师页面进行同样的操作。你会发现简介在所有教师间是共享的,因为代码块是添加到 template中的, 而 biography t模板在所有教师间是共享的,编辑一个页面时同时也编辑了其它页面。

针对具体记录的数据应当对记录进行保存,所以我们来为教师新增一个简介字段:

academy/models.py

academy/templates.xml

重启Odoo并更新视图,重新加载教师页面,这个字段会不可见,因为其中不包含内容。

对于记录字段,模板可以使用特殊的 t-field 指令,它允许使用针对字段的页面编辑网站中的字段内容。修改 person 模板来使用 t-field

academy/templates.xml

重启Odoo并升级模块,现在在教师姓名下有一个占位符,并在编辑模式下有一个新代码块区域。拖到这里的内容会存储到对应教师的 biography 字段中,因此会具体到对应教师。

教师的姓名也可以进行编辑,并在保存修改后在首页中可见。

t-field 也可以接收依赖于具体字段的格式化选项。例如如果我们要展示教师记录的修改日期:

academy/templates.xml

它以一个非常“计算机”的方式展示,难以阅读,但我们可以要求一个易于人类阅读的版本:

academy/templates.xml

或一个相对的展示:

academy/templates.xml

网站支持 一节中我们简单地接触了Odoo管理。 可以使用菜单中的 Administrator ‣ Administrator加到这个页面(如果登出的话请进行登录)。

Odoo后台的概念结构很简单:

  1. 首先是菜单,一个树状的记录(菜单中可包含子菜单)。不包含子集的菜单映射到…
  2. 动作。动作有多种类型:链接、报表、Odoo应当执行代码或数据展现。数据展现也称为window动作,告诉Odoo根据一组视图…展示一个给定的模型。
  3. 视图拥有类型,一个其响应的广泛类型(列表、图表、日历),自定义在视图顺模型展示方式的结构。

默认,Odoo模型对用户基本是隐藏的。让要其可见,必须通过动作,动作本身通常通过菜单来让人们可对其进行访问。

我们来为自己的模型创建一个菜单:

academy/__manifest__.py

academy/views.xml

然后访问 http://localhost:8069/web/ ,左上角应该会有一个菜单Academy,默认为已选状态,因为它是第一个菜单,并会打开一个教师列表。通过列表可以新建教师记录,并通过记录视图切换到“表单”视图。

如果没有对如何展示记录的定义(视图) ,Odoo会自动补时创建一个基本的展示。本例中现在“列表”视图的展示没有问题(仅展示教师姓名),但在“表单”视图中HTML biography字段与name字段并排展示,没有给予足够的空间。我们来自定义一个表单视图来让浏览和编辑教师记录的体验更好:

academy/views.xml

我们了解到了在记录中直接存储的一组”基础“字段。还有很多基础字段。第二个广泛的分类是关联,用于记录之间彼此链接(在同一个模型中或跨模型)。

我们来创建一个courses 模型。每个课程应有一个 teacher 字段,链接到单个教师记录,但每个教师可以教授多门课程:academy/models.py

academy/security/ir.model.access.csv

我们也来添加视图,这样可以查看并编辑一个课程的教师:

academy/views.xml

还应当可以直接通过教师页面来新建一个课程,或者查看他们所教授的所有课程,因此为teachers模型添加一个反向关联

academy/models.py

academy/views.xml

Odoo提供了技术模型,它们不直接满足业务需求,但增加了无需手动构建而实现业务对象的可能性。

其中之一就是Chatter 系统,Odoo的email和消息系统的一部分,它可以为任意模型添加通知和讨论线程。模型只需要通过 _inherit mail.thread,并向其表单视图添加 message_ids 字段来展示讨论线程。讨论线程是记录级的。

对于我们的academy项目,允许有课程的讨论来处理如计划更改或进行教师和助教之间的讨论是有现实意义的:

academy/models.py

academy/views.xml

在每个课程表单的底部, 现在都会有一个讨论线程并让系统的用户可以进行留言或关注及取消关注与具体课程相关联的讨论。

Odoo还提供业务模型,它允许更直接地使用或实现业务需求。例如  website_sale 模型根据Odoo系统中的产品来建立一个电商网站。我们可以轻松地把课程变成某种商品来让课程可销售。

不同于前面的经典继承,这表示通过product模型替换我们的course模型,并在当前位置扩展商品模型(为我们所需的内容)。

首先我们需要添加一个对website_sale 的依赖,因此可以获取商品 (通过 sale)及电商界面:

academy/__manifest__.py

重启Odoo,更新模块,在网站中会出一个Shop版块,列出一系第(通过演示数据)预填充的商品。

第二步是通过product.template替换 courses 模型,并新增一个针对课程的商品分类:

academy/__manifest__.py

academy/data.xml

academy/demo.xml

academy/models.py

academy/security/ir.model.access.csv

academy/views.xml

安装之后,一些课程现在在Shop中就可以使用了,但需要进行查找。

截至目前,我们简单的学习了:

剩下对已有记录的修改及已有视图的修改。我们将对Shop页面进行这两者的修改。

视图的修改通过创建继承视图来实现,它应用于原视图之上并对其进行修改。这些修改视图可以无需对原始视图进行修改来新增或删除,这让我们进行试验和回滚都变得更为简单。

因为我们的课程是免费的,不需要在shop页面显示价格,因此我们将修改视图来在价格为0时进行婚期。第一个任务是找到展示价格的视图,这可通过Customize ‣ HTML Editor来实现,它让我们读取涉及渲染页面的不同模型。进行了一些查看后我们发现“Product item”可能是负责这个内容的。=

修改视图结构通过3个步骤来完成:

  1. 新建视图
  2. 通过设置新视图的 inherit_id 为所修改视图的外部 id 来扩展修改视图
  3. 在这个结构中,使用xpath标记来选择并修改来自所修改视图中的元素

academy/templates.xml

我们所做的第二个修改是让商品边栏通过默认的Customize ‣ Product Categories可见,这样可以开启、关闭一个树状商品分类(用于过滤主显示内容)。

这通过继承模型的 customize_show 和 active 字段来实现:一个继承模板(例如我们所创建的)可以为 customize_show=True。这一选项会在自定义菜单中以复选框进行显示,允许管理员启用或禁用它们(并易于自定义他们的网页)。

我们只需修改Product Categories 记录并设置其默认为 active=”True”:

academy/templates.xml

至此, Product Categories边栏就会在安装了Academy模块之后自动启用了。

退出移动版