跳转至内容

Odoo 开发与实施交流

2.3k 主题 10.4k 帖子

No decsciption available

  • odoo12 与IE兼容问题

    2
    0 赞同
    2 帖子
    1k 浏览
    在页面上直接调试下css,然后修改下。我上次网站有遇到这样的情况,调试出然后扩展将css更改下就行。
  • 如何在tree视图上分页

    8
    1
    0 赞同
    8 帖子
    3k 浏览
    M
    @hui 没有实现呢,这个是别人做的模型,我需要按照模型在odoo上去创建
  • [已解决]odoo12中Sale Order如何自动生成Purchase Order

    4
    0 赞同
    4 帖子
    2k 浏览
    H
    @digitalsatori sale_stock模块中没有action_confirm方法。 需要依赖purchase_stock模块,继承stock.rule模型,重写_run_buy方法。生成Purchase Order是在这个方法中的。
  • 0 赞同
    7 帖子
    3k 浏览
    W
    参考方案: 1)在views中定义一个client action: Test myproject.test current 2)使用一个html a元素来触发这个action: Test 3)编写一个js widget,具体写法参考文档:https://www.odoo.com/documentation/12.0/reference/javascript_reference.html#widgets; 主要做三件事: a)设定模板template,根据要显示tree的需求去定制; b)定义willStart函数,使用._rpc()函数与后端通讯获得模型数据; c)定义start()函数,使用上一步获取的数据来render画面; 完成widget之后,调用core.action_registry.add()来注册这个widget,使得点击上文的html a元素,就会显示这个widget 4)最后一步,在后端模型类添加方法,用于被js _rpc()函数调用来获取数据;
  • 0 赞同
    1 帖子
    671 浏览
    如题,补充包请自行下载测试web_diagram_extend.rar 很久没有发言了,回来凑个热闹
  • Windows下64 位电脑 安装的odoo为什么是32位的?

    3
    0 赞同
    3 帖子
    1k 浏览
    L
    若不使用odoo自带的python启动 有模块不支持64位的python 比如win32service,odoo本身也有32位与64位区别吧,不过现在已用docker安装
  • 此主题已被删除!

    1
    0 赞同
    1 帖子
    8 浏览
  • 错误系统自带的功能报错

    2
    0 赞同
    2 帖子
    883 浏览
    G
    升级一下base模块 然后再试试
  • 通过上传按钮添加的文件,过段时间会消失,找不到下载文件

    2
    0 赞同
    2 帖子
    915 浏览
    JoshuaJ
    可以检查下是否在配置文件设置了文件目录位置data_dir。
  • Odoo 开发手册连载五 导入、导出以及模块数据

    1
    1 赞同
    1 帖子
    1k 浏览
    S
    本文为最好用的免费ERP系统Odoo 12开发手册系列文章第五篇。 英文原著为Odoo 12 Development Essentials - Fourth Edition By Daniel Reis ➣第一章 使用开发者模式快速入门 Odoo 12 ➣第二章 Odoo 12开发之开发环境准备 ➣第三章 Odoo 12 开发之创建第一个 Odoo 应用 ➣第四章 Odoo 12 开发之模块继承 ➣第五章 Odoo 12开发之导入、导出以及模块数据 ➣第六章 Odoo 12开发之模型 - 结构化应用数据 ➣第七章 Odoo 12开发之记录集 - 使用模型数据 ➣第八章 Odoo 12开发之业务逻辑 - 业务流程的支持 ➣第九章 Odoo 12开发之外部 API - 集成第三方系统 ➣第十章 Odoo 12开发之后台视图 - 设计用户界面 ➣第十一章 Odoo 12开发之看板视图和用户端 QWeb ➣第十二章 Odoo 12开发之报表和服务端 QWeb ➣第十三章 Odoo 12开发之创建网站前端功能 ➣第十四章 Odoo 12开发之部署和维护生产实例 大多数Odoo 模块的定义,如用户界面和安全规则,实际是存储在对应数据表中的数据记录。模块中的 XML 和 CSV 文件不是 Odoo 应用运行时使用,而是载入数据表的手段。正是因为这个原因,Odoo 模块的一个重要部分是在文件中放入数据以在插件安装时将其载入数据库。 模块可以包含初始数据和演示数据,可通过数据文件将它们加入模块。此外,了解 Odoo 数据的格式对于在项目实施上下文中导入导出业务数据也非常重要。 本文的主要内容有: 理解外部标识符的概念 导入导出数据文件 使用 CSV 文件 添加模块数据 使用 XML 数据文件 开发准备 本文要求读者可以运行Odoo 服务并已安装前面我们此前开发的图书应用。相关代码请见GitHub 仓库。你可能也同时安装了第四章 Odoo 12 开发之模块继承中创建的library_member模块,但本文并不要求使用该模型。 本文的更新后的代码请见GitHub 仓库。 理解外部标识符的概念 外部标识符,也称为XML ID,是用于唯一标识 Odoo 中特定记录的有可读性的字符串标识符。在Odoo 中加载数据时它们就很重要了,这样可以对已有数据记录进行修改或在其它数据记录中引用它。 首先我们将讨论外部标识符的工作原理以及如何对其进行检查。然后我们会学习如何使用网页客户端来查找指定数据记录的外部标识符,在创建插件模块或继承已有模块时需要经常用到。 外部标识符的工作原理 记录在数据库中的真实标识符是自动分配的序列号,在安装模块时没法预先知道将要分配的具体ID的。外部标识符让我们无需知道真实的数据库 ID便可以引用一条相关记录。XML ID 为数据库 ID 提供了一个方便的别名,藉于此我们可以在任何时刻引用某一指定记录。 Odoo 模块数据文件中使用XML ID来定义记录。其中一个原因是避免在升级模块时创建重复的记录,在升级时会再次将数据文件加载到数据库中。我们要检测已有记录来进行更新,而不是重复创建记录。另一个原因是使用XML ID来支持交叉数据:即需引用其它数据记录的数据记录。因为我们无法知道真实数据库 ID,使用XML ID来由 Odoo 框架来进行相应的转换。 Odoo 处理由外部标识符向所分配的真实数据库 ID 的转换。背后的机制相当简单:Odoo 维护一张外部标识符和对应数据库 ID 的映射表:ir.model.data model。 我们需启用开发者模式才能访问下文中的菜单。可通过在右上角头像左侧查看是否有调试图标,如果没有需在 Settings菜单页启用,具体方法可参照第一章 使用开发者模式快速入门 Odoo 12中的内容。 通过菜单访问Settings > Technical > Sequences & Identifiers > External Identifiers可查看已有映射。例如访问外部标识符列表并过滤出library_app模块,将可以看到该模块生成的外部标识符: [image: 1240] 可以看到外部标识符有Complete ID标签。注意其组成部分为:模块名+.+标识符名,如library_app.action_library_book。 外部标识符仅需在 Odoo 模块内唯一,两个模块中使用相同标识符不会产生冲突。全局唯一标识符是由模块名和外部标识符共同组成的,在上图Complete ID项中可以看到。 在数据文件中使用外部标识符,我们可以选择完整的标识符或仅外部标识符部分。通常仅使用外部标识符会更简单,但使用完整标识符时我们可以引用其它模块中的数据记录。做引用时不要忘记在模块依赖中加入这些模块以确保在我们的记录之前加载这些记录。 **小贴士:**有时即便引用相同模块中的XML ID也需使用完整标识符 在上图列表最上方可以看到library_app.action_library_book完整标识符。这是我们在模块中创建的菜单操作,在相应的菜单项中引用。点击进入表单视图查看详情。图中可以看出library_app模块中的action_library_book外部标识符映射到ir.actions.act_window模型中的记录 ID,此处为85: [image: 1240] 除了作为其它应用引用记录的一种方式外,外部标识符还可以避免重复导入带来的重复数据。一旦外部标识符已存在,则会在原有记录上更新,避免了重复数据的新建。 查找外部标识符 在为我们的模块写入数据记录时,经常需要查找已有外部标识符来作引用。一种方式是访问菜单Settings > Technical > Sequences & Identifiers > External Identifiers,前面已经演示过。另一种方法是使用开发者菜单。在第一章 使用开发者模式快速入门 Odoo 12中介绍了如何激开发者模式。 要查找一个数据记录的外部标识符,我们应打开对应的表单视图,在开发者菜单中选择View Metadata选项。此时会显示一个带有记录数据库 ID 和外部标识符(也称作XML ID)的对话框。比如要查看 demo 用户 ID,需通过 Settings > Users & Companies > Users 进入用户表单视图,然后点击开发者工具菜单中的View Metadata选项。此时可以看到XML ID是base.user_demo,数据库 ID 是6: [image: 1240] 查看表单、列表、搜索或 action 视图中的外部标识符,都可以使用开发者菜单。下面我们通过Edit View选项来打开相应视图的详情表单。此时可以查看到External ID字段,其值即为外部标识符。例如在下图中,可以看到图书表单视图的External ID为library_app.view_form_book: [image: 1240] 导入导出 CSV 数据文件 导出数据文件并查看文件结构的简易方式是使用内置的导出功能。通过生成 CSV 文件,我们可以了解手动导入系统所需的格式,或编辑该文件批量导入,甚至是使用它生成我们插件模块的演示数据。 下面我们一起来学习从 Odoo 用户界面导入和导出的基础知识。 导出数据 数据导出是表单视图中的标准功能。要使用该功能, 需要勾选左侧的复选框来选择需导出的行,然后在上方的 Action 菜单中点击 Export 选项。首先我们要在图书应用中添加一些带有出版商和作者的图书。下例中我使用此前添加的书籍。 我们还需要安装 Contacts 应用,这样可以看到 Partner 的列表视图,可从该处导出记录。注意其默认视图为带有名片的看板视图,需要先切换为列表视图: [image: 1240] 可通过勾选列头的筛选框来选择所有匹配当前搜索条件的记录。 ️Odoo 9中的修改 在 Odoo 更早的版本中,只有屏幕上显示(当页)的记录能被导出。Odoo 9做出了修改,勾选列头的复选框可导出当前过滤的所有匹配记录,而不仅仅是当前显示。这对导出屏幕上无法展示全的大量记录非常有用。 点击 Export 选项进入Export Data 对话表单,可选择导出方式。我们比较关注的是导出方式可以让我们通过手动或插件模块来导入该文件: [image: 1240] 在对话表单最上方,有两个选项: What do you want do do?(老版本中为Export type),选择Import-Compatible Export选项,这样导出数据在以后导入时格式更友好。 Export formats:可选择CSV或Excel,我们将选择 CSV 格式来更好理解原始导出格式,在很多表单应用中都能被读取。 下一步选取要导出的列,本例中简化操作,仅选择External ID和Name。如果我们点击Export To File按钮,就会下载带有导出数据的文件。最终的 CSV 内容类似: "id","name" "__export__.res_partner_45_5b73e404","Kaiwan N Billimoria" "__export__.res_partner_42_49816b0d","Packt" "__export__.res_partner_44_9e374a59","Russ McKendrick" "__export__.res_partner_43_e38db1b7","Scott Gallagher" **补充:**伸手党请注意这里及后续的 ID 字段都与导出的系统有关,不应直接使用 第一行中包含列名,导入时会使用它们自动匹配目录列。导出内容有两列: id:为每条记录分配的外部 ID,如果不存在,会在模块名处使用__export__ 作为前缀自动生成一条新ID。 name: 联系人/Partner 名称 带有外部 ID 使我们可以编辑导出数据并重新导入来把修改更新到记录中。 **小贴士:**由于会自动生成记录 id,导出或导入功能可用于批量编辑 Odoo 数据:将数据导出至 CSV,使用表单软件批量编辑数据,再导入 Odoo。 导入数据 首先应确认开启了导入功能,默认是开启的。如果没有,进入Settings > General Settings,在 Users 版块下勾选Import & Export选项即可。启用该选项后,列表视图上方 Create 按钮旁就会显示一个 Import按钮。 **注意:**Import & Export 设置安装base_import模块,该模块用于提供这一功能。 下面我们尝试批量编辑Contact或Partner数据。使用电子表单或文本编辑器打开CSV并修改几个值。将 id 栏留空即可新增行。前文已经提到第一列 id 作为每行的唯一标识符,这让已有记录可以被更新,而不会因重新导入数据重复创建。我们在导出表中编辑任意字段在导入时对应记录就会被更新。 对于要加入 CSV 文件的新行,我们可以自己添加外部标识符或将 id 列留空。两种方式都会创建新的记录。作为示例,我们添加一行id 留空、name 为Phillip K. Dick,来在数据库中新建这一记录。在 CSV文件中进行保存,点击 Import(Create 按钮旁),然后点击 Load File 按钮选择磁盘中 CSV 的路径就出会出现如下导入助手: [image: 1240] 点击右上角的Test Import按钮,检查数据正确性。由于导入的文件是在 Odoo 中导出文件基础上修改的,正常会有效并且各列会自动与数据库中对应字段匹配。因编辑所使用的软件各异,有可能需对分隔符和编码进行处理。现在可以点击 Import 按钮,修改和新建记录就会被载入到 Odoo 中。 [image: 1240] CSV 数据文件中的关联记录 前面的示例非常简单,一旦我们开使用关联多张表的关联字段时,数据文件就会变得更为复杂。我们处理过图书中的 Partner 记录,下面就看一下如何在图书 CSV 文件中表示对这些 Partner 的引用。具体来说,有一个出版商(publisher_id字段)的many-to-one(或外键)关联,以及一个作者(author_ids字段)的many-to-many关联。 CSV 文件的表头行中关联列应在名称后添加一个/id。它将使用外部标识符来引用关联记录。本例中,我们将在publisher_id/id字段中加载图书出版商,使用关联 Partner 的外部 ID 作为其值。 **注意:**可使用/.id来进行替代来使用数据库中的真实 ID(自动分配的数字 id),但极少使用到。除非有特别原因,否则请使用外部 ID 而非数据库ID。同时要记住数据库 ID 针对具体的数据库,所以如果导入到非原始数据库中这种操作大多数情况下都会失败。 CSV 数据文件中也可导入many-to-many字段,这和添加带双引号并由逗号分隔的外部 ID 列表一样简单。例如,要载入图书作者,将需要一个author_ids/id列,并使用一个关联 Partner外部 ID 的逗号分隔列表作为其值: id, name, author_ids/id book_docker, "Mastering Docker - Third Edition","__export__.res_partner_44_767f4606,__export__.res_partner_43_b97c9264" [image: 1240] One-to-many 字段通常是表头和行或父子关系,对于这类关系有特别的支持方式:对于同一条父记录可以有多个关联行。此处我们在 Partner 模型中有一个 one-to-many字段的例子:公司可带有多个联系人。如果从 Partner 模型中导出数据并包含Contacts/Name 字段,就可以看到要导入此类型数据的格式(Contacts 中选择Azure Interior:默认应为第一条,并执行前述的导出步骤): | id | name | child_ids/id | child_ids/name | | base.res_partner_12 | Azure Interior | base.res_partner_address_15 | Brandon Freeman | |   |   | base.res_partner_address_28 | Colleen Diaz | |   |   | base.res_partner_address_16 | Nicole Ford | [image: 1240] id和 name 列为父记录的,child_ids两列为子记录的。注意第一行记录以下父记录部分留空。上表中CSV 文件形式显示为: "id","name","child_ids/id","child_ids/name" "base.res_partner_12","Azure Interior","base.res_partner_address_15","Brandon Freeman" "","","base.res_partner_address_28","Colleen Diaz" "","","base.res_partner_address_16","Nicole Ford" 可以看到id和name这两列第一行有值,后两行都为空。其中的父记录为联系人的公司信息。另两行的前缀都是child_ids/并且在三行中都有数据。这些是父公司的联系人信息。第一行包含公司和第一个联系人,其余行仅包含联系人这一子信息。 添加模块数据 模块使用数据文件来加载默认数据、演示数据、用户界面定义和其它需存入数据库的配置。可以选择使用 CSV 或 XML 文件。 ️Odoo 12中的修改 Odoo 11及之前版本支持YAML格式文件,但在 Odoo 12移除了相关支持。相关使用示例可参考 Odoo 11官方模块l10n_be,更多YAML格式相关信息,可访问http://yaml.org/。 模块所使用的 CSV 和我们前述使用导入功能时用的文件是一样的。在模块中使用这些文件时,文件名须与要导入数据的模型名一致。例如,导入library.book模型的 CSV 数据文件名应为library.book.csv。CSV 数据文件经常用作导入ir.model.access模型来获取权限定义,通常放在security/子目录下并命名为ir.model.access.csv。 演示数据 Odoo插件模块可安装演示数据,推荐支持该安装。为模块提示使用示例和测试用的数据集会非常有用。模块的演示数据通过__manifest__.py文件中的 demo 属性来声明。和 data 属性一样,后接一个包含模块相对路径的文件名列表。我们应为library.book模块添加一些演示数据,一个简易方式是从安装了模块的开发数据库中导出数据。 按惯例数据文件放在data/子目录下,应以data/library.book.csv保存在library_app模块下。因这个数据为模块所有,应在导出的数据中将标识符的前缀__export__去除。 例如res.partner.csv文件可能长这样: id,name res_partner_alexandre,"Alexandre Fayolle" res_partner_daniel,"Daniel Reis" res_partner_holger,"Holger Brunn" res_partner_packt,"Packt Publishing" 那么图书演示数据文件library.book.csv就应该是这样的: "id","name","date_published","publisher_id/id","author_ids/id" library_book_ode11,"Odoo Development Essentials 11","2018-03-01",res_partner_packt,res_partner_daniel library_book_odc11,"Odoo 11 Development Cookbook","2018-01-01",res_partner_packt,"res_partner_alexandre,res_partner _holger" 注意文件中同一条数据因显示原因可能在不同行中,但实际是不能换行的。还应记得在__manifest__.py的 demo 属性中声明数据文件: 'demo': [ 'data/res.partner.csv', 'data/library.book.csv', ], 文件会以声明的顺序来加载,这个很重要,因为文件可能会因为未被安装而无法引用其记录。只要启用了安装演示数据,下次更新时,这些内容就会被导入。 ️数据文件会在模块升级时重新导入,但演示文件则并非如此,它们仅在安装时导入。 当然 XML 文件也可用于加载或初始化数据,还可使用普通 CSV 文件所不具备的功能。 使用 XML 数据文件 CSV 文件是一种展示数据方便简洁的格式,但 XML 文件更为强大,可在加载过程中提供更多的控制。比如,其文件名无需与所导入到的模型名称一致。因为XML格式通过文件内的XML元素可以提供更丰富的信息、更多的内容。 在前面的文章中我们已经使用过XML数据文件。视图和菜单项这类用户界面组件实际上都是存储在系统模型中的记录。模块中的XML文件是将这些记录加载到实例数据库的方式。我们将在library_app模块中添加一个数据文件data/book_demo.xml来作为展示,文件内容如下: <?xml version="1.0"?> <odoo noupdate="1"> <!-- Data to load --> <record model="res.partner" id="res_partner_huxley"> <field name="name">Aldous Huxley</field> </record> <record model="library.book" id="library_book_bnw"> <field name="name">Brave New World</field> <field name="author_ids" eval="[(4, ref('res_partner_huxley'))]" /> <field name="date_published">1932-01-01</field> </record> </odoo> 老规矩,新的数据文件应在__manifest__.py中声明: 'demo': [ ... 'data/book_demo.xml', ], 类似 CSV 文件,该文件也会将数据加载到图书模型中。 [image: 1240] XML文件包含一个外层元素,内部可包含多个元素与对应 CSV 数据行。 ️数据文件中的外层元素在9.0中才引入用于替换此前的标签。现在仍支持外层元素内的标签,为可选项。事实上现在和是等价的,我们可以在数据文件中使用任意一个作为外层元素。 元素有两个强制属性: model 和作为记录外部标识符的 id,每个字段使用一个标签来进行写入。注意此处字段名内不可使用斜杠标记,如不可使用。应使用 ref 属性来引用外部标识符,一会儿就会讨论到关联 to-many 字段。 你可能注意到在外层元素中使用了noupdate="1"属性。这防止了在模块升级时数据记录的载入,不至于在后续编辑中丢失数据。 noupdate 数据属性 升级模块时,会重新加载数据并重写模块记录。要谨记这可能意味着在升级模块时会重写任何对模块数据的手动更改。 **小贴士:**值得注意的是,手动对视图所做的自定义修改会在下一次模块升级时丢失。避免这一问题正确的方法是创建继承视图来引入要做的修改。 这种重写行为是默认的,但可以修改有些数据仅在安装时导入,后续模块更新时则予以忽略,这正是通过或元素中的noupdate="1"来实现的。 这对于需初始化配置且预期需自定义的数据来说非常有用,因为这些手动修改在模块更新时是安全的。例如在记录访问规则中经常使用,可以适应具体的实施需求。 在同一 XML 文件中可以有多个版块。可通过这个来分隔仅需导入一次的数据(noupdate="1")和需在每次更新时重新导入的数据(noupdate="0")。noupdate="0"是默认值,所以可以省略不写。注意还必须要有一个外层 XML 元素,就这个例子而言,使用两个标签,并在外层包裹一个或元素。 **小贴士:**noupdate属性在开发模块时可能会引起不适,因为会忽略后续修改。一个解决方案是,使用-i 参数重新安装模块而不是使用-u 参数进行更新。命令行中使用-i 参数重新安装会忽略数据记录中的noupdate标记。 noupdate标记存储在每条记录的外部标识符信息中。可通过 Technical 菜单中的External Identifiers表单手动编辑,勾选Non Updatable 复选框即可。 ️Odoo 12中的修改 点击开发者菜单中的View Metadata时,现在在弹出的对话框中 XML ID 下面还会显示No Update的值。并且在该处可通过点击来修改该标记的值。 在 XML 中定义记录 在 XML 文件中,每个元素有两个基本属性:id 和 model,并包含为对应列设置的值。 id 属性对应记录外部标识符,model 对应目标模型。元素有几种分配值的方法,下面一起来看看。 直接为字段设置值 元素的 name 属性标识要写入的字段。写入的值是元素内容:字段开、闭标签之间的文本。对于 date 和datetime,带有返回 date 或 datetime 对象表达式的 eval 属性可进行设置。返回的"YYYY-mm-dd"和"YYYY-mm-dd HH:MM:SS"字符串会进行转化。对于布尔字段,"0" and "False"都会转换成 False,而任意非空值都会转换成 True。 小贴士:Odoo 10中的修改 Odoo 10中改进了从数据文件中读取布尔值 False的方式。在老版本中,包含"0" and "False"在内的非空值都会转换成 True,直至 Odoo 9,布尔值仍需使用 eval 属性进行设置,如 eval="False"。 通过表达式设置值 设置字段值更复杂的方式是通过 eval 属性,它会运行 Python 表达式并将结果分配给字段。表达式通过 Python 内置的以及一些其它可创建表达式标识符的上下文求值。 可使用如下 Python 模块来处理日期:time, datetime, timedelta和relativedelta。通过它们可以计算日期值,在演示和测试数据经常会用到,以让日期和模块安装日期较近。关于 Python 模块更多这类知识,请参考官方文档。 比如,把值设为前一天,可使用如下代码: <field name="date_published" eval="(datetime.now() + timedelta(-1))" /> 求值上下文还可使用ref()函数,用于将外部标识符转换为对应的数据库 ID。这可用于为关联字段设置值。比如,可以使用它为publisher_id设置值: <field name="publisher_id" eval="ref('res_partner_packt')" /> 在 many-to-one 关联字段上设置值 对于many-to-one关联字段,要写入的是关联记录的数据库 ID。在 XML 文件中,我们一般会知道记录的XML ID,然后就需要把它转换成实际的数据库 ID。 一种方式是像前文那样使用带有 ref()函数的 eval 属性。更简单的替代方式是使用在元素中可用的ref 属性,使用它设置publisher_id many-to-one字段的值,我们可以这么写: <field name="publisher_id" ref="res_partner_packt" /> 在 to-many 关联字段上设置值 对于one-to-many和many-to-many字段,设置的不是单个 ID,而是一组关联 ID。并且还进行几种操作-我们可能需要将当前的关联记录列表替换成另外一个,或为其添加几次记录,甚至是删除其中的一些记录。 要让to-many字段支持写操作,我们要在 eval 属性中使用一种特殊的语法。我们使用一个元组组成的列表来写入to-many字段。每个元组有三个元素,构成一个写入命令,根据第一个元素中的代码进行对应操作。要重写图书作者列表,要使用如下代码: <field name = "author_ids" eval = "[(6, 0, [ref('res_partner_alexandre'), ref('res_partner_holger')] )]" /> 要往当前图书作者列表添加关联记录,需要添加如下代码: <field name="author_ids" eval="[(4, ref('res_partner_daniel'))]" /> 上述的例子非常常见。这里仅使用了一个命令,但在外层列中可以串联多条命令。添加(4)和 替换(6)是最常用的命令。在进行添加(4)时,不需要使用最后一个元素,因此在以上代码中省略了。 完整的可用命令如下: (0, _ , {'field': value})新建一条记录并将其与之关联 (1, id, {'field': value})更新已关联记录的值 (2, id, _)移除关联并删除 id 关联的记录 (3, id, _)移除关联但不删除 id 关联的记录。通常使用它来删除many-to-many字段的关联记录 (4, id, _)关联已存在记录,仅适用于many-to-many字段 (5, _, _)删除所有关联,但不删除关联记录 (6, _, [ids])替换已关联记录列表为此处的列表 上述下划线_字符代表非关联值,通常填入 o 或 False。 **小贴士:**后面的非关联值可以放心地省略掉,如(4, id, _) 可使用(4, id) 常用模型的简写 如果回到第三章 Odoo 12 开发之创建第一个 Odoo 应用,我们在 XML 中还发现之外的元素,如<act_window>和。这些是常用模型的简写方式,是比常用的更为简练的符号。它们用于向 base 模型加载数据、组成用户界面,在第十章 Odoo 12开发之后台视图 - 设计用户界面会作更详细的探讨。 为便于查看,以下是可用的简写元素以及加载数据的对应模型: <act_window>是窗口操作模型ir.actions.act_window 是菜单项模型ir.ui.menu 是报表操作模型ir.actions.report.xml 是存储在ir.ui.view模型中的 QWeb 模板 ️Odoo 11中的修改 标签已被淘汰并删除。此前的版本中它用作为 URL 操作模型ir.actions.act_url加载记录。 应当注意在用于修改已有记录时,简写元素会覆盖所有字段。这与仅写入所提供字段的基础元素不同。因此在需修改用户界面元素指定字段时,应使用元素。 XML 文件中的其它操作 截至目前我们了解了如何使用 XML 文件添加和更新数据。但也可以通过 XML 文件删除数据以及执行指定模型方法。对更复杂的数据场景会非常有用。 删除记录 我们可以使用元素删除数据记录,使用 ID 或搜索域来定位要删除的记录。例如,使用搜索域查找记录并删除: <delete model="res.partner" search="[('id','=',ref('library_app.res_partner_daniel'))]" /> 如果知道要删除记录的具体 ID,可使用 id 属性。上例还可以写成这样: <delete model="res.partner" id="library_app.res_partner_daniel" /> 调用模型方法 XML 文件还可以通过元素在加载过程中执行任意方法,可用于设定演示和测试数据。比如 Odoo 捆绑的 Notes 应用,使用它来设定演示数据: <data noupdate="1"> <function model="res.users" name="_init_data_user_note_stages" eval="[]" /> </data> 这会调用res.users模型中的_init_data_user_note_stages方法,不传任何参数。由参数列表eval传递,此处为空列表。 总结 本文中我们学习了如何在文件文中展示数据。可用作手动向 Odoo 导入数据,或放在插件模块中作为默认或演示数据。通过学习我们可以通过网页界面导出并导入 CSV 数据文件了,以及通过外部 ID 来检测并更新数据库中已有的记录。也可用作批量编辑数据,只需编辑导出的 CSV 文件再重新导入即可。 我们还详细学习了 XML 数据文件的结构以及所提供功能。不仅可以为字段设置值,还可以执行删除记录和调用方法一类的操作。 下一篇文章中,我们将集中学习如何使用记录来与模型中所含数据协作。这些工具可供我们实现应用的业务逻辑和规则。 ☞☞☞第六章 Odoo 12开发之模型 - 结构化应用数据 学霸专区 XML ID 与外部 ID 的区别是什么? 插件模块中可使用什么类型的数据文件? 以下 XML 片段有什么问题? <field name="user_id">[(4, 0, [ref(base.user_demo)])]</field> 一个插件模块中的数据文件是否可以覆盖另一个模块中创建的记录? 插件模块升级时,是否所有数据记录都会被重写为模块默认值? 扩展阅读 Odoo 官方文档中提供了有关数据文件的更多资料。 本文首发地址:Alan Hou的个人博客
  • 最新odoo12 nginx反向代理

    1
    0 赞同
    1 帖子
    1k 浏览
    M
    如下图,nginx设置proxy_set_header后,会出现 2019-02-02 16:00:11,698 141152 WARNING goodman odoo.http: No CSRF validation token provided for path '/web/login' Odoo URLs are CSRF-protected by default (when accessed with unsafe HTTP methods). See https://www.odoo.com/documentation/12.0/reference/http.html#csrf for more details. * if this endpoint is accessed through Odoo via py-QWeb form, embed a CSRF token in the form, Tokens are available via `request.csrf_token()` can be provided through a hidden input and must be POST-ed named `csrf_token` e.g. in your form add: <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/> * if the form is generated or posted in javascript, the token value is available as `csrf_token` on `web.core` and as the `csrf_token` value in the default js-qweb execution context * if the form is accessed by an external third party (e.g. REST API endpoint, payment gateway callback) you will need to disable CSRF protection (and implement your own protection if necessary) by passing the `csrf=False` parameter to the `route` decorator. 2019-02-02 16:00:11,701 141152 WARNING goodman odoo.addons.website.models.ir_ui_view: Could not find view object with xml_id 'website.400' 且无法登陆进去 proxy_set_header配置为 proxy_set_header Host $host; proxy_set_header X–Real–IP $remote_addr; proxy_set_header X–Forwarded–For $proxy_add_x_forwarded_for; proxy_set_header X–Forwarded–Proto $scheme; 如果把proxy_set_header注释掉,nginx反向代理就可以访问,但是一修改头像就会提示 连接已丢失...重新连接,无法修改,而且没有修改头所有发送的连接仍是localhost或者是ip地址
  • Odoo 开发手册连载四 Odoo 12 开发之模块继承

    1
    1 赞同
    1 帖子
    1k 浏览
    S
    本文为最好用的免费ERP系统Odoo 12开发手册系列文章第四篇。 英文原著为Odoo 12 Development Essentials - Fourth Edition By Daniel Reis ➣第一章 使用开发者模式快速入门 Odoo 12 ➣第二章 Odoo 12开发之开发环境准备 ➣第三章 Odoo 12 开发之创建第一个 Odoo 应用 ➣第四章 Odoo 12 开发之模块继承 ➣第五章 Odoo 12开发之导入、导出以及模块数据 ➣第六章 Odoo 12开发之模型 - 结构化应用数据 ➣第七章 Odoo 12开发之记录集 - 使用模型数据 ➣第八章 Odoo 12开发之业务逻辑 - 业务流程的支持 ➣第九章 Odoo 12开发之外部 API - 集成第三方系统 ➣第十章 Odoo 12开发之后台视图 - 设计用户界面 ➣第十一章 Odoo 12开发之看板视图和用户端 QWeb ➣第十二章 Odoo 12开发之报表和服务端 QWeb ➣第十三章 Odoo 12开发之创建网站前端功能 ➣第十四章 Odoo 12开发之部署和维护生产实例 Odoo 的一个强大功能是无需直接修改底层对象就可以添加功能。这是通过其继承机制来实现的,采取在已有对象之上修改层来完成。这种修改可以在不同层上进行-模型层、视图层和业务逻辑层。我们创建新的模块来做出所需修改而无需在原有模块中直接修改。 上一篇文章中我们从零开始创建了一个新应用,本文中我们学习如何通过继承已有的核心应用或第三方模块来创建新的模块。实现以上本文将主要涵盖: 原模型扩展,为已有模型添加功能 修改数据记录来继承视图,添加功能或修改数据来修改其它模块创建的数据记录 其它模型继承机制,如代理继承和 mixin 类 继承 Python 方法来为应用业务逻辑添加功能 继承 Web 控制器和模板来为网页添加功能 开发准备 本文要求可通过命令行来启动 Odoo 服务。代码将在第三章 Odoo 12 开发之创建第一个 Odoo 应用的基础上进行修改。通过该文的学习现在我们已经有了library_app模块。本系列文章代码请参见 GitHub 仓库。 学习项目-继承图书馆应用 在第三章 Odoo 12 开发之创建第一个 Odoo 应用中我们创建了一个图书应用的初始模块,可供查看图书目录。现在我们要创建一个library_member模块,来对图书应用进行扩展以让图书会员可以借书。它继承 Book 模型,并添加一个图书是否可借的标记。该信息将在图书表单和图书目录页显示。 应添加图书会员主数据模型Member,类似 Partner 来存储个人数据,如姓名、地址和 email,还有一些特殊字段,如图书会员卡号。最有效的方案是代理继承,自动创建图书会员记录并包含关联 Partner 记录。该方案使得所有的Partner 字段在 Member 中可用,没有任何数据结构上的重复。 我们还要在借书表单中为会员提供消息和社交功能,包括计划活动组件来实现更好地协作。我们还要添加会员从图书馆中借书的功能,但暂不涉及。以下是当前所要修改内容的总结: 图书 添加一个Is Available? 字段。现在通过手动管理,以后会自动化 扩展 ISBN 验证逻辑来同时支持10位数的ISBN 扩展图书目录页来分辨不可借阅图书并允许用户过滤出可借图书 会员 添加一个新模型来存储姓名、卡号和 Email、地址一类的联系信息 添加社交讨论和计划活动功能 首先在library_app同级目录创建一个library_member目录来作为扩展模块,并在其中添加两个文件,一个__init__.py空文件和一个包含如下内容的__manifest__.py文件: { 'name': 'Library Members', 'description': 'Manage people who will be able to borrow books.', 'author': 'Alan Hou', 'depends': ['library_app'], 'application': False, } 原模型继承 第一步我们来为Book模型添加is_available布尔型字段。这里使用经典的 in-place 模型继承。该字段值可通过图书借出和归还记录自动计算,但现在我们先使用普通字段。要继承已有模型,需要在 Python 类中添加一个_inherit 属性来标明所继承的模型。新类继承父 Odoo 模型的所有功能,仅需在其中声明要做的修改。在任何地方使用该模型修改都可用,可以认为这类继承是对已有模型的引用并在原处做了一些修改。 为模型添加字段 通过 Python 类来新建模型,继承模型同样是通过 Python 以及 Odoo 自有的继承机制,即_inherit 类属性。该属性标明所继承的模型。新的类继承父 Odoo 模型的所有功能,仅需声明要做修改的部分。编码指南推荐为每个模型创建一个 Python 文件,因此我们添加library_member/models/library_book.py文件来继承原模型,首先创建__init__.py文件来导入该文件: 1、添加library_member/init.py文件来导入 models 子文件夹 from . import models 2、添加library_member/models/init.py文件子文件夹中的代码文件: from . import library_book 3、创建library_member/models/library_book.py文件来继承library.book模型: from odoo import fields, models class Book(models.Model): _inherit = 'library.book' is_available = fields.Boolean('Is Available?') 使用_inherit类属性来声明所继承模型。注意我们并没有使用到其它类属性,甚至是_name 也没使用。除非想要做出修改,否则不需要使用这些属性。 ️_name是模型标识符,如果修改会发生什么呢?其实你可以修改,这时它会创建所继承模型的拷贝,成为一个新模型。这叫作原型继承,本文后面会讨论。 可以把这个想成是对模型定义的一个引用,在原处做了一个修改。可以添加字段、修改已有字段、修改模型类属性甚至是包含业务逻辑的方法。要在数据表中添加新的模型字段需要安装该模块。如果一切顺利,通过Settings > Technical > Database Structure > Models菜单查看library.book模型即可看到该字段。 ~/odoo-dev/odoo/odoo-bin -d dev12 -i library_member [image: 1240] 修改已有字段 通过上面部分可以看到向已有模型添加新字段非常简单。有时还要对已有字段进行修改,也非常简单。在继承模型时,可对已有字段叠加修改,也就是说仅需定义要增加或修改的字段属性。 我们将对原来创建的library_app模块的 Book模型做两处简单修改: 为isbn字段添加一条提示,说明同时支持10位数的 ISBN(稍后会实现该功能) 为publisher_id字段添加数据库索引,以提升搜索效率 编辑library_member/models/library_book.py文件,并在library.book 模型中添加如下代码: class Book(models.Model): ... isbn = fields.Char(help="Use a valid ISBN-13 or ISBN-10.") publisher_id = fields.Many2one(index=True) 这会对字段进行指定属性修改,未涉及的属性不会被修改。升级模块,进入图书表单,将鼠标悬停在 ISBN 字段上,就可以看到所添加的提示信息了。index=True这一修改不太容易发现,通过Settings > Technical > Database Structure > Models菜单下的字段定义中可进行查看。 [image: 1240] 修改视图和数据 模块中视图和其它数据构件也可通过继承来修改。就视图而言,通常需要添加功能。视图的展示结构在 arch 字段中使用 XML定义。这一 XML 数据可通过定位到所需修改的地方来进行继承,然后声明需执行的操作,如在该处添加 XML 元素。对于剩余的数据元素,它们代表写入数据库中的记录,继承模型可通过写操作来修改它们的值。 继承视图 表单、列表和搜索视图通过arch XML结构定义。要继承视图,就要一种修改 XML 的方式,也即定位 XML 元素然后对该处进行修改。视图继承的 XML 记录和普通视图中相似,多一个 inherit_id属性来引用所要继承的视图。下面我们来继承图书视图并添加is_available字段。 首先要查找待继承的视图的XML ID,通过Settings > Technical > User Interface > Views菜单来查看。图书表单的XML ID是library_app.view_form_book。然后还要找到要插入修改的XML元素,我们在 ISBN 字段之后添加Is Available?通常通过name 属性定位元素,此处为。 我们添加views/book_view.xml文件来继承 Partner 视图,加入如下内容: <?xml version="1.0"?> <odoo> <record id="view_form_book_extend" model="ir.ui.view"> <field name="name">Book: add Is Available? field</field> <field name="model">library.book</field> <field name="inherit_id" ref="libary_app.view_form_book" /> <field name="arch" type="xml"> <field name="isbn" position="after"> <field name="is_available" /> </field> </field> </record> </odoo> 以上代码中,我们高亮显示了继承相关的元素。inherit_id记录字段通过 ref 属性指向继承视图的外部标识符,我们将在第五章 Odoo 12开发之导入、导出以及模块数据讨论外部标识符详情。视图使用 XML 定义并存储在结构字段 arch 中。要继承一个视图,先定位要扩展的节点,然后执行要做的操作,如添加 XML 元素。 定位节点的最简单方法是使用唯一标识属性,通常是 name。然后添加定位属性,声明要做的修改。本例中继承节点是name="isbn"元素,修改是在选定元素后加一段 XML: <field name="isbn" position="after"> <!-- 此处添加修改内容 --> </field> 除string 属性外的任意 XML 元素和属性可作为继承节点,字符串属性会被翻译成用户所使用的语言,因此不能作为节点选择器。 ️在9.0以前,string 属性(显示标签文本)也可作为继承定位符。在9.0之后则不再允许。这一限制主要源自这些字符串的语言翻译机制。 一旦 XML 节点被选为继承点,需要指明要执行的继承操作。这通过 position 属性实现: inside(默认值):在所选节点内添加内容,这一节点应是或一类的容器 after:在选定节点之后向父节点添加内容 before:在选定节点之前向父节点添加内容 replace:替换所选节点。若使用空元素则会删除该元素。Odoo 之后还允许使用其它标记来包裹元素,通过在内容中使用$0来表示被替换的元素。 attributes:修改匹配元素属性值。内容中应包含带有一个或多个<attribute name="attr-name">value元素。如True,若不带内容,如则 attribute 会从所选元素中删除。 **小贴士:**通过position="replace"可删除 XML 元素,但应避免这么做。这么做会破坏其它依赖所删除节点、将其作为占位符添加元素的模块。一个替代方案是,让该元素不可见。 除了attributes定位,上述定位符可与带position="move"的子元素合并。效果是将子定位符目标节点移到父定位符目录位置。 ️Odoo 12中的修改 position="move"子定位符是 Odoo 12中新增的,之前的版本中没有 例如: <field name="target_field" position="after"> <field name="my_field" position="move"/> </field> 其它视图类型,如列表和搜索视图,也有 arch 字段,可以表单视图同样的方式被继承。 在声明文件data 中加入该视图文件并更新模块即可: [image: 1240] 使用 XPath 选取继承点 有时可能没有带唯一值的属性来用作 XML 节点选择器。在所选元素没有 name 属性时可能出现这一情况,如、或视图元素。另外就是有多个带有相同 name 属性的元素,比如在看板 QWeb 视图中相同字段可能在同一 XML 模板中被多次包含。 在这些情况下我们就需要更高级的方式来定位待扩展 XML 元素。定位 XML 中元素的一种自然方式是 XPath 表达式。以上一篇文章中定义的 Book 表单视图为例,定位元素的 XPath 表达式是//field[@name]='isbn'。该表达式查找 name 属性等于 isbn 的元素。 前一部分对图书表单视图继承的 XPath 写法是: <xpath expr="//field[@name='isbn']" position="after"> <field name="is_available" /> </xpath> XPath 语法的更多知识请见 Python 官方文档。 如果 XPath 表达式匹配到了多个元素,仅会选取第一个作为扩展目录。所以表达式应越精确越好,使用唯一属性。name 属性最易于确保找到精确元素作为扩展点,因此在创建视图 XML 元素时添加唯一标识符就非常重要。 修改数据 普通数据记录不同于视图,它没有 XML arch 结构,也不能使用 XPath 来进行扩展。但还是可以通过替换字段值来进行修改。 数据加载元素实际是对 y 模型进行插入或更新操作。若不存在记录 x,则被创建,否则被更新/覆盖。其它模块中的记录可通过.全局标识符访问,因此可以在我们的模块中重写其它模块中已写入的数据。 ️点号是保留符号,用于分隔模块名和对象标识符,所以在标识符名中不要使用点号,而应使用下划线字符。 举个例子,我们将 User 安全组的名称修改为 Librarian,对应修改library_app.library_group_user记录。添加library_member/security/library_security.xml并加入如下代码: <odoo> <!-- Modify Group name --> <record id="library_app.library_group_user" model="res.groups"> <field name="name">Librarian</field> </record> </odoo> 这里我们使用了一个元素,仅写了 name 字段。可以认为这是对所选字段的一次写操作。 **小贴士:**使用元素时,可以选择要执行写操作的字段,但对 shortcut 元素则并非如此,如和<act_window>。它们需要提供所有的属性,漏写任何一个都会将对应字段置为空值。但可使用为原本通过 shortcut 元素创建的字段设置值。 在声明文件data 中加入security/library_security.xml并更新模块即可看到效果。 [image: 1240] 其它模型继承机制 前面我们介绍了模型的基本继承,在官方文档中称为经典继承。这是最常用的继承方式,最容易想到的就是in-place继承。获取模型并对其继承。添加的新功能会自动添加到已有模型中,而不会创建新模型。 可以为_inherit 属性传入多个值来继承多个父模型。大多数情况下这通过 mixin 类完成,mixin类是实现可复用的通用功能。也可以像普通模型那样独立使用,像是一个功能容器,可随时加到其它模型中。 如在使用_inherit 属性的同时还使用了与父模型不同的_name属性,此时会复用所继承并创建一个新的模型,并带有自己的数据表和数据。官方文档称其为原型(prototype)继承。下面我们会拿一个模型,并为其创建一个拷贝。在添加新功能时,只会被加到新模型中,而不会变更原模型。 此外还有代理(delegation)继承,通过_inherits 属性来使用(注意最后有一个 s)。这允许我们创建一个包含和继承已有模型的新模型。新模型创建新记录时,在原模型中也会被创建并使用many-to-one 字段关联。查看新模型的人可以看到所有原模型和新模型中的字段,但在后台两个模型分别处理各自的数据。 下面我们一起来了解详情。 使用原型继承拷贝功能 前文我们继承模型时使用了_inherit 属性,创建一个类继承library.book 并添加了一些功能。类中没有使用_name属性,不指明即使用library.book。如果设置了不个不同值的_name 属性,会通过从所继承的模型拷贝功能创建新模型。 在实际开发中,这类继承一般通过抽象 mixin 类,很少这样直接继承普通模型,因为这样会创建冗余的数据结构。Odoo 还有一种代理继承机制可避免这类数据结构冗余,所以普通模型通常会使用这种方法来做继承。 使用代理继承内嵌模型 使用代理继承无需复制数据即可在数据库中复用数据结构,这通过将一个模型嵌入另一个来实现。UML 中这种称作组合(composition)关系:父类无需子类即可存在,而子类必须要有父类才能存在。 比如,对于内核 User模型,每条记录包含一条 Partner 记录,因此包含 Partner 中的所有字段以及User自身的一些字段。 在图书项目中,我们要添加一个图书会员模型。会员有会员卡并通过会员卡借阅读书。我们要记录卡号,还要存储email 和地址这类个人信息。Partner 模型已包含联系和地址信息,所以最好是进行复用,而不去创建重复的数据结构。 为会员模型创建library_member/models/library_member.py文件并加入如下代码: from odoo import fields, models class Member(models.Model): _name = 'library.member' _description = 'Library Member' card_number = fields.Char() partner_id = fields.Many2one( 'res.partner', delegate=True, ondelete='cascade', required=True) 使用代理继承,library.member 中嵌入了继承模型res.partner,因此在创建会员记录时,一个关联的 Partner 会自动被创建并通过partner_id字段引用。 ️Odoo 8中的修改 在新的 API 中引入了delegate=True字段属性。在那之前,代理继承通过模型属性来定义,类似_inherits = {'res.partner': 'partner_id'}。现在仍支持这一写法,官网中还有相应介绍,但delegate=True 字段属性可起到相同效果且使用更简单。 透过代理机制,嵌套模型的所有字段就像父模型字段一样自动可用。本例中,会员卡模型可使用 Partner 中的所有字段,如 name, address和 email,以及会员自身的独有字段,如card_number。在后台中,Partner 字段存储在关联的 Partner 记录,没有重复的数据结构。 ️对于模型方法则并非如此,Partner 模型中的方法在 Member 模型中不可使用。 与原型继承相比,代理继承的好处在于无需跨表重复像地址这样的数据。任何需包含地址的新模型通过代理嵌入了 Partner 模型。如果在 Partner 中修改 address字段,在所有嵌入的模型中可以马上使用。 **小贴士:**代理继承可通过如下组合来进行替代: 父模型中的一个 many-to-one 字段 重载 create()方法自动创建并设置父级记录 父字段中希望暴露的特定字段的关联字段 有时这比完整的代理继承更为合适。例如res.company并没有继承res.partner,但使用到了其中好几个字段。 不要忘记在library_member/model/init.py文件中加入: from . import library_book from . import library_member 要使用我们创建的 Member 模型,还要完成以下步骤: 添加安全权限控制列表(ACL) 添加菜单项 添加表单和列表视图 更新manifest文件来声明这些新增数据文件 读者可以先尝试自己添加,再来看下面的详细步骤: 要创建安全ACL,创建library_member/security/ir.model.access.csv文件并加入如下代码: id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_member_user,Member User Access,model_library_member,library_app.library_group_user,1,1,1,0 access_member_manager,Member Manager Access,model_library_member,library_app.library_group_manager,1,1,1,1 要添加菜单项,创建library_member/views/library_menu.xml文件并加入如下代码: <odoo> <act_window id="action_library_member" name="Library Members" res_model="library.member" view_mode="tree,form" /> <menuitem id="menu_library_member" action="action_library_member" parent="library_app.menu_library" /> </odoo> 要添加视图,创建library_member/views/member_view.xml文件并加入如下代码: <?xml version="1.0" ?> <odoo> <record id="view_form_member" model="ir.ui.view"> <field name="name">Library Member Form View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <form> <group> <field name="name" /> <field name="email" /> <field name="card_number" /> </group> </form> </field> </record> <record id="view_tree_member" model="ir.ui.view"> <field name="name">Library Member List View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <form> <group> <field name="name" /> <field name="card_number" /> </group> </form> </field> </record> <record id="view_tree_member" model="ir.ui.view"> <field name="name">Library Member List View</field> <field name="model">library.member</field> <field name="arch" type="xml"> <form> <group> <field name="name" /> <field name="card_number" /> </group> </form> </field> </record> </odoo> 最后,编辑manifest文件来声明这三个新文件: 'data':[ ... 'security/ir.model.access.csv', 'views/library_menu.xml', 'views/member_view.xml', ] 如果编写正确,在进行模型更新后即可使用新的图书会员模型了。 ~/odoo-dev/odoo/odoo-bin -d dev12 -u library_member [image: 1240] 使用 mixin类继承模型 原型继承主要用于支持 mixin 类。mixin 是基于 models.Abstract 的抽象的模型(而不是models.Model),它在数据库中没有实际的体现,而是提供功能供其它模型复用(混合 mixed in)。Odoo 插件提供多种 mixin,最常的两种由 Discuss 应用(mail 模块)提供: mail.thread提供在许多文档表单下方或右侧的消息面板功能,以及消息和通知相关逻辑。这在我们自己的模型中将经常会添加,下面就来一起学习下。 mail.activity.mixin模型提供待办任务计划。 ️Odoo 11中的修改 mail 模块现在通过mail.activity.mixin抽象模型提供Activities任务管理功能。该功能在 Odoo 11中才添加,此前的版本中没有。 我们一起来为 Member 模型添加上述两种 mixin。社交消息功能由 mail 模块的mail.thread模型提供,要将其加入自定义模型,应进行如下操作: 通过 mixin 模型 mail 为插件模块添加依赖 让类继承mail.thread和mail.activity.mixin两个 mixin 类 将message_follower_ids, message_ids和activity_id这些 mixin 的数据字段添加到表单视图 对于第一步扩展模型需要在__manifest__.py文件中添加对 mail 的依赖。 'depends': ['library_app', 'mail'], 第二步中对 mixin 类的继承通过_inherit属性完成,应编辑library_member/models/library_member.py并添加如下代码: class Member(models.Model): _name = 'library.member' _description = 'Library Member' _inherit = ['mail.thread', 'mail.activity.mixin'] ... 通过添加额外的这行代码,我们的模型就会包含这些 mixin 的所有字段和方法。 第三步中向表单视图添加相关字段,编辑library_member/views/member_view.xml文件并在表单最后添加如下代码: <odoo> ... <form> ... <!-- mail mixin fields --> <div class="oe_chatter"> <field name="message_follower_ids" widget="mail_followers" /> <field name="activity_ids" widget="mail_activity" /> <field name="message_ids" widget="mail_thread" /> </div> </form> mail 模块还为这些字段提供了一些特定的网页组件,以上代码中已使用到。在升级模块后会员表单将变成这样: [image: 1240] 有时普通用户仅能访问正在 follow 的记录。在这些情况下我们应添加访问记录规则来让用户可以看到 follow 的记录。本例中用不到这一功能,但可通过[('message_partner_ids', 'in', [user.partner_id.id])]或来进行添加。 继承 Python 方法 Python 方法中编写的业务逻辑也可以被继承。Odoo 借用了 Python 已有的父类行为的对象继承机制。 作为一个实际的例子,我们将继承图书 ISBN 验证逻辑。在图书应用中仅能验证13位的 ISBN,但老一些的图书可能只有10位数的 ISBN。我们将继承_check_isbn()方法来完成这种情况的验证。在library_member/models/library_book.py文件中添加如下方法: from odoo import api, fields, models class Book(models.Model): ... @api.multi def _check_isbn(self): self.ensure_one() isbn = self.isbn.replace('-', '') digits = [int(x) for x in isbn if x.isdigit()] if len(digits) == 10: ponderators = [1, 2, 3, 4, 5, 6, 7, 8, 9] total = sum(a * b for a, b in zip(digits[:9], ponderators)) check = total % 11 return digits[-1] == check else: return super()._check_isbn() 要继承方法,我们要重新定义该方法,可以使用 super()来调用已实现的部分。在这个方法中我们验证是否为10位数 ISBN,然后插入遗失的验证逻辑。若不是10位,则进入原有的13位验证逻辑。 如果想要进行测试甚至是书写测试用例,可使用0-571-05686-5作为例子,该书是威廉·戈尔丁的《蝇王》。 ️Odoo 11中的修改 从 Odoo 11开始,支持的主Python版本为 Python 3(Odoo 12中为 Python 3.5)。而此前的 Odoo 版本使用 Python 2,其中 super()需传入类名和 self 两个参数,那么,上例中的代码应修改为super(Book, self)._check_isbn()。 [image: 1240] 继承 Web 控制器和模板 Odoo 中的所有功能都带有扩展性,web 功能也不例外,所以已有控制器和模块都能被继承。 作为示例,我们将继承图书目录网页,加入前面添加的图书可用性信息: 在控制器端添加对查询参数的支持,访问/library/books?available=1过滤出可借阅图书 在模板端,添加一个图书不可用的表示 继承网页控制器 网页控制器不应包含实际业务逻辑,仅集中于展示逻辑。我们可能会需要添加对额外 URL 参数甚至是路由的支持,来改变网页的展示。我们将扩展/library/books来支持available=1参数,以过滤出可借阅图书。 要继承已有控制器,需导入对应对象,然后用方法新增逻辑来进行实现。下面新增ibrary_member/controllers/main.py文件并加入如下代码: from odoo import http from odoo.addons.library_app.controllers.main import Books class BookExtended(Books): @http.route() def list(self, **kwargs): response = super().list(**kwargs) if kwargs.get('available'): Book = http.request.env['library.book'] books = Book.search([('is_available', '=', True)]) response.qcontext['books'] = books return response 我们要继承的Books控制器在library_app/controllers/main.py中定义。因此需要通过odoo.addons.library_app.controllers.main导入。这和模型不同,模型可以通过 env 对象中的central registry 来引用任意模型类,而无需了解实现它的文件。控制器没有这个,我们需要知道实现需继承控制器的模块和文件。 然后基于Books声明了一个BooksExtended类,类名不具关联性,仅用于继承和扩展原类中定义的方法。 再后我们(重)定义了一个控制器方法 list()。它至少需要一个简单的@http.route()装饰器来保持路径活跃。如果不带参数,将会保留父类中定义的路由。但也可以为@http.route() 装饰器添加参数,来重新定义或替换类路由。 在继承的 list()方法中,一开始使用了 super()来运行已有代码。处理结果返回一个 Response 对象,Response 带有模块要渲染的属性 template,以及渲染使用的上下文qcontext。但还需要生成 HTML,仅会在控制器结束运行时生成。这也让我们可以在最终渲染完成之前可以修改 Response 属性。 list()方法带有**kwargs参数,捕获所有kwargs字典中的参数。这些是 URL 中的参数,如?available=1。方法检测kwargs中available键的值,检测到后改变qcontext来获取仅为可借阅图书的图书记录集。 还要记得让模块知道这个新 Python 文件,需通过将 controllers 子文件夹中添加到library_member/init.py中: from . import models from . import controllers 在library_member/controllers/init.py文件中添加一行代码: from . import main 然后更新模板并访问http://:8069/library/books?available=1 将仅显示勾选了Is Available? 的图书 [image: 1240] 继承 QWeb 模板 要修改网页的实际展示,就需要继承所使用的 QWeb 模板。我们将继承library_app.book_list_template来展示更多有关不可借阅图书的信息。添加library_member/views/book_list_template.xml文件并加入如下代码: <odoo> <template id="book_list_extended" name="Extended Book List" inherit_id="library_app.book_list_template"> <xpath expr="//span[@t-field='book.publisher_id']" position="after"> <t t-if="not book.is_available"> <b>(Not Available)</b> </t> </xpath> </template> </odoo> 网页模板像其它 Odoo 视图类型一样是 XML 文件,同样也可以使用 XPath 来定位元素并对它们进行操作。所继承模型通过在元素中的inherit_id来指明。 **小贴士:**在前例中使用了灵活性很强的 XPath 标记,但这里也可以使用等价的简化标记: 然后在 library_member/manifest.py文件中加入该文件的声明: 'data':[ ... 'views/book_list_template.xml', ] 然后访问http://:8069/library/books即可对不可借阅图书展示额外的(Not Available)信息。 [image: 1240] 总结 扩展性是 Odoo 框架的一个重要功能。我们可以创建插件来为需要实现功能的多个层的已有插件修改或添加功能。 模型层中,我们使用_inherit模型属性来引用已有模型,然后在原处执行修改。模型内的字段对象还支持叠加定义,这样可对已有字段重新声明,仅修改属性。 其它的模型继承机制允许我们利用数据结构和业务逻辑。代理继承通过多对一关联字段上的delegate=True属性(或老式的 inherits 模型属性),来让所有关联模块的所有字段可用,并复用它们的数据结构。原型继承使用_inherit属性,来复制其它模型的功能(数据结构定义和方法),并启用抽象 mixin 类,提供一系列像文档讨论消息和 follower 的可复用功能。 视图层中,视图结构通过 XML 定义,(使用 XPath 或 Odoo 简化语法)定位 XML 元素来进行继承及添加 XML 片断。其它由模块创建的记录已可由继承模块修改,仅需引用 对应的完整 XML ID 并在设想的字段上执行写操作。 业务逻辑层中,可使用模型继承相同的机制来进行继承,以及重新声明要继承的方法。在方法内,Python 的super()函数可用于调用所继承方法的代码,添加代码可在其之前或之后运行。 对于前端网页,控制器中的展示逻辑继承方式和模型方法相似,网页模板也是包含 XML 结构的视图,因此可以像其它视图类型一样的被继承。 下一篇文章中,我们将更深入学习模型,探索模型提供给我们的所有功能。 ☞☞☞第五章 Odoo 12开发之导入、导出以及模块数据 学霸专区 如何继承已有模型来添加 minin,如mail.thread? 要在会员表单视图中添加Phone字段需要做哪些修改? 如果创建一个与继承属性的属性名不同的模型类会发生什么(例如_name='y' and _inherit='x')? XPath是否可用于修改其它模块的数据记录? 继承一个模型时,是否可扩展其方法但不使用 super()调用所继承的原始代码? 如何在不引用任何特定字段名的情况下继承图书目录页并在末行添加 ISBN 字段? 扩展阅读 以下是对官方文档的其它引用,可对模块的扩展和继承机制的知识进行补充: 模型继承 视图继承 网页控制器 本文首发地址:Alan Hou 的个人博客
  • odoo12 中在tree视图中新增自定义按钮

    9
    0 赞同
    9 帖子
    5k 浏览
    H
    @seasid 在js中可以获取到当前view的id,获取方法: this.__parentedParent.views.list.view_id 就看怎么获取到自定义的tree view的id,然后对比下应该就可以了 ps:js获取这些值,都可以通过console.log(this),在这里面找应该都可以找到的。
  • 此主题已被删除!

    1
    0 赞同
    1 帖子
    40 浏览
  • Odoo 12 开发之创建第一个 Odoo 应用

    5
    0 赞同
    5 帖子
    4k 浏览
    S
    @digitalsatori 一听就知道是老江湖了,还请多提意见
  • Odoo 12开发之开发环境准备

    2
    1 赞同
    2 帖子
    2k 浏览
    S
    本文为最好用的免费ERP系统Odoo 12开发手册系列文章第二篇。 英文原著为Odoo 12 Development Essentials - Fourth Edition By Daniel Reis ➣第一章 使用开发者模式快速入门 Odoo 12 ➣第二章 Odoo 12开发之开发环境准备 ➣第三章 Odoo 12 开发之创建第一个 Odoo 应用 ➣第四章 Odoo 12 开发之模块继承 ➣第五章 Odoo 12开发之导入、导出以及模块数据 ➣第六章 Odoo 12开发之模型 - 结构化应用数据 ➣第七章 Odoo 12开发之记录集 - 使用模型数据 ➣第八章 Odoo 12开发之业务逻辑 - 业务流程的支持 ➣第九章 Odoo 12开发之外部 API - 集成第三方系统 ➣第十章 Odoo 12开发之后台视图 - 设计用户界面 ➣第十一章 Odoo 12开发之看板视图和用户端 QWeb ➣第十二章 Odoo 12开发之报表和服务端 QWeb ➣第十三章 Odoo 12开发之创建网站前端功能 ➣第十四章 Odoo 12开发之部署和维护生产实例 在更深入了解 Odoo 开发之前,我们应配置好开发环境并学习相关的基础管理任务。本文中,我们将学习创建 Odoo 应用所需用到的工具和环境配置。这里采用 Ubuntu 系统来作为开发服务器实例的主机,可以是云服务器、本地服务器或者PC 上的虚拟机。 本文主要内容有: 配置主机,可以是 Ubuntu系统或 PC 机上的 Linux 子系统 使用源码安装 Odoo,包括数据库和系统依赖的安装 管理 Odoo 数据库(创建、删除和拷贝) 配置 Odoo 服务器选项 查找并安装社区插件 使用虚拟环境管理 Odoo 不同版本和项目 开启服务端开发者模式简化开发任务 开发准备 本文将介绍如何在开发电脑上使用源码安装 Odoo,建议使用系统是Ubuntu 18.04 ,也可以选择 Windows 10,文中会介绍到如何在 Windows 下安装 Linux 子系统。相关代码可参见 GitHub 仓库。 设置 Odoo 服务宿主机 推荐使用Debian/Ubuntu来运行 Odoo 服务。虽然 Odoo 是一个跨平台的系统,可以运行在不同的操作系统上,但事实上 Odoo 的研发(R&D)团队把 Debian 系作为参照部署平台。并且 Odoo 自己的 SaaS 平台也运行在 Debian 之上。这也是社区中最主流的选择,说明使用Debian 或 Ubuntu 会更容易寻求到帮助和建议。你也许仅有 Windows 相关背景,但对Debian 系有一定了解也非常重要。 当然你依然可以选择自己喜欢的系统,如 Windows, Mac 或其它Linux发行版本(如 CentOS)。 注意:本文中介绍的是在一个全新的系统中进行开发,如果你在已有系统中开发,请做好备份以在出错时进行恢复 使用 Windows 子系统安装 Linux 在 Windows 系统中,最简单的方案是使用 Windows 10自带的Linux子系统(WSL - Windows Subsystem for Linux)。通过子系统,我们可以在 Windows 内运行 Ubuntu 系统,足以应对 Odoo 开发所需的一切。更多 WSL 相关知识请参考官网。 WSL 是Windows 10最近发布中的一个可选功能,使用前需要先启用。启用后即可在商店中安装 Ubuntu,详见官方帮助文档。 在写本文时,需要如下步骤来完成安装: 第一步是要确保 WSL 功能已开启,以管理员身份打开 PowerShell 并运行: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux 以上命令需要单行执行,然后根据提示重启电脑。然后我们就可以安装Ubuntu Windows应用,最简单地方式是在自带微软商店中搜索 Ubuntu,在写本文时最新的长期支持版本(LTS)是18.04,按照提示进行安装即可。运行 Ubuntu 应用会打开一个bash 命令行,这里可以输入在 Ubuntu 系统中相同的命令。需要记住在安装时配置的用户名和密码,因为在进行提权操作时会要求输入该信息(如运行 sudo 时)。 安装 Linux 服务器 我们还可以选择在电脑上安装 Linux,或在局域网乃至云端安装 Linux 系统。我们需要一台基于 Debian 的服务器用于 Odoo 服务端开发,如果此前你没有接触过 Linux, 请注意 Ubuntu 是一个基于 Debian 的 Linux 发行版本,所以两者极为相似。Odoo 保证可在当前稳定的 Debian 或 Ubuntu 版本上运行,在写本文时,分别为 Debian 9(Stretch)和Ubuntu 18.04 LTS(Bionic Beaver)。 更推荐选择 Ubuntu,因安装上较 Debian 容易。可从 Ubuntu 官网上下载 ISO 镜像,建议使用最新的 LTS 版本。如果你刚刚接触 Linux,使用预配置的镜像会更容易些。TurnKey Linux提供了含 ISO 的多种格式预安装镜像。ISO 格式可以在任意虚拟化软件上使用,即便是裸机。较优的选择是 LAPP 镜像,已安装了 Odoo 所需的Python 和 PostgreSQL。 为能够进行远程操作,通常需安装OpenSSH服务。在 Ubuntu 的设置助手中有这一服务,但也可以通过如下命令来进行安装: sudo apt-get install openssh-server 然后需要使用 SSH(Secure Shell)客户端来连接 Odoo 的宿主机,Windows 中常用的有 PuTTY、XShell 和 SecureCRT。 可以通过如下命令来查看服务器的 IP 地址: ip addr show 使用 SSH 客户端可以远程操作 Linux 主机,还可以获得比在虚拟机终端操作更好的体验,我们可以更容易的复制粘贴、修改窗口大小、字体等。 **补充:**关于虚拟机 Hyper-V,  VMware, VirtualBox和 Vagrant 都是很好的方案,网上有很多资料,限于篇幅本文不再介绍。 源码安装 Odoo 在本系列文件第一篇使用开发者模式快速入门 Odoo 12中,我们介绍了快速运行 Odoo 的各种方式,本文中我们将更深入一步,直接通过源码来安装、运行 Odoo。 Odoo使用Python 编程语言,数据存储使用 PostgreSQL数据库,这是对 Odoo 主机的两大要求。要使用源码运行 Odoo,首先要安装其所依赖的 Python 库。然后从 GitHub 上下载源代码,虽然可以下载 zip 和 tar 文件,但使用 Git版本管理工具获取代码会更优。 具体依赖的安装根据操作系统和安装的 Odoo 版本可能会不同。如果在上述步骤中存在问题,请参考官方文档,可切换版本查看其它版本的操作步骤。 安装 PostgreSQL 数据库 Odoo 要使用到 PostgreSQL服务,典型的开发设置是使用安装 Odoo 的同一台机器安装PostgreSQL。下我们就来安装数据库服务: sudo apt update sudo apt install postgresql # 安装PostgreSQL sudo su -c "createuser -s $USER" postgres # 创建数据库超级用户 最后这条命令为当前系统用户创建了一个PostgreSQL用户,用于 Odoo 实例创建或删除数据库时使用。 如果在 WSL内运行 Ubuntu,注意系统服务不会自动启动。也就是说运行任何需要数据库连接的命令(如createuser或启动 Odoo 服务)时都要手动开启PostgreSQL服务,手动启动PostgreSQL服务执行:sudo service postgresql start。 安装 Odoo 系统依赖 要运行 Odoo,我们还需要一些系统包和软件。获取版本控制的源码应安装 Git,安装运行 Odoo要求 Python 3.5或之后的版本、Python 3的 pip 以及一些 Python 包的系统依赖: sudo apt update sudo apt upgrade sudo apt install git # 安装Git sudo apt install python3-dev python3-pip # Python 3 for dev sudo apt install build-essential libxslt-dev libzip-dev libldap2-dev libsasl2-dev libssl-dev Odoo 9, 10, and 11版要用到less CSS 预处理器,所以对这些版本需要执行如下安装: sudo apt install npm # 安装Node.js和包管理器 sudo ln -s /usr/bin/nodejs /usr/bin/node # 通过node运行Node.js sudo npm install -g less less-plugin-clean-css # 安装less Odoo 12中无需执行如上命令,但通常我们也会用到前述版本,如果有此情况则仍需安装。 Odoo 12中的修改 CSS 预处理器由 less 改成了 Sass,Sass 编译器无需进行额外安装,在 Odoo 12的 Python 依赖中已经安装了libsass-python。做出这一更改的原因有:Bootstrap 4由 less 调整为 Sass,已有 Python绑定和避免对 Node.js(或 Ruby)的依赖。 源码安装 Odoo 为便于管理,我们将在家目录下创建一个/odoo-dev目录作为工作目录。在本系列文章中我们均假设 Odoo 安装在/odoo-dev目录下。 Odoo 使用的是 Python 3(3.5或之后的版本),那么在命令行中我们将不再使用python和pip,而是用python3和 pip3。 Odoo 11的修改 从版本11开始,Odoo 运行在 Python 3.5及以后的版本上,Odoo 11依然支持 Python 2.7,但 Odoo 12仅能运行在Python 3.5+的环境中。Odoo 10及之前的版本仅可运行在Python 2.7上。 要从源码安装 Odoo,我们首先要从 GitHub 上克隆一套 Odoo 源代码: mkdir ~/odoo-dev # 创建工作目录 cd ~/odoo-dev # 进入工作目录 git clone https://github.com/odoo/odoo.git -b 12.0 --depth=1 # 获取 Odoo 源码 ~是用户家目录的缩写,比如/home/alan。 如果使用 WSL Windows 子系统,家目录存放在一个Windows 系统文件夹中一个不易于发现的地方。避免这一情况的一个方法是把工作文件放在常用的文件夹下,然后在子系统中使用软链接(类似 Windows中的快捷方式)。比如mkdir /mnt/c/Users/Public/odoo-dev创建C:\Users\Public\odoo-dev工作目录,然后ln -s /mnt/c/Users/Public/odoo-dev ~/odoo-dev创建~/odoo-dev Linux目录,实际上是 Windows 目录的链接。现在就可以使用~/odoo-dev运行所有的命令,比如前述的 git 克隆,文件将存放在C:\Users\Public\odoo-dev下。 Git命令中的-b 12.0明确表明要下载 Odoo 12.0分支,在写本文时,这显得有些多余,因为这正是当前默认的分支。--depth=1表示仅下载当前修订版本,而不是所有历史修改记录,这会使下载更快、内容更少。 **小贴士:**如需在后续下载历史提交内容,可以运行git fetch - -unshallow 在运行 Odoo 之前,应安装requirements.txt中所声明的 Python 依赖: pip3 install -r ~/odoo-dev/odoo/requirements.txt **补充:**安装时如因requirements.txt指定了Babel==2.3.4而报错,请修改Babel==2.3.4为Babel或 Babel>=2.3.4后再重新执行以上命令;另内存过小也可能导致不易察觉报错,测试时1G 内存报错,调整为2G 后正常安装 这其中的很多依赖都可以通过 Debian 包安装,如python3-lxml,所以使用 apt 包管理器是一个有效的替代方案。这样的优势是在必要时可以自动安装系统依赖,使用的依赖列表可以在./odoo/debian/control中找到。 还有一些requirements.txt中未包含的 Python 包,亦可安装来避免警告或开启额外的功能: pip3 install num2words phonenumbers psycopg2-binary watchdog xlwt **小贴士:**pip3工具可以通过好几种方式安装:系统包的方式和原生 Python 的方式。如果pip3报了 import error,在系统中重新安装或能解决问题。对应的命令为sudo python3 -m pip uninstall pip && sudo apt install python3-pip --reinstall 现在,通过如下命令可启动 Odoo 实例: ~/odoo-dev/odoo/odoo-bin 如需停止服务并回到命令行,按下 Ctrl + C。 小贴士:Odoo 10中的修改 现在启动 Odoo的脚本是./odoo-bin,而之前的 Odoo 版本中为./odoo.py 默认Odoo 实例监听8069端口,所以在浏览器中访问http://:8069 就可以访问到 Odoo 实例。对于开发者来说,我们会需要使用到多个数据库,所以在命令行中创建会更为方便,后面会介绍如何实现。现在在命令行终端中按下Ctrl + C 停止 Odoo 服务并回到命令行。 初始化新的 Odoo 数据库 要按照 Odoo 的数据模式创建和初始化 Odoo 数据库,我们应使用-d 参数运行 Odoo 服务: ~/odoo-dev/odoo/odoo-bin -d testdb 初始化 testdb 数据库可能要花上一分钟,一般会以Modules loaded的 INFO 日志信息结束。它有可能不是最后一条日志信息,但在倒数三到四行中可以找到。此时,服务器就可以监听用户请求了。 Odoo 9中的修改 从 Odoo 9开始,如果数据库不存在会被自动创建。但在 Odoo 8中并非如此,需使用PostgreSQL命令行中的createdb命令手动创建 默认情况下,数据库初始化时会带有演示数据,作为开发数据库这通常很有用。相当于在前端创建数据库时勾选了Load demonstration data。如在初始化时无需带有演示数据,在命令行中添加--without-demo=all。 **小贴士:**在写本文时Ubuntu WSL中有一个针对 PostgreSQL 的问题,该环境下无法新建空数据库。一个解决方案是手动通过createdb 12-library命令创建空数据库。这样会重复提示WARNING: could not flush dirty data: Function not implemented。虽然存在警告信息,但数据库正常创建了。按下Ctrl + C停止警告,使用命令行即可启动 Odoo 并初始化数据库。 当前用户需要是 PostgreSQL 的超级用户才能创建新数据库,前文中在安装过程中已经进行相关操作。 **小贴士:**对于开发环境,使用数据库超级用户来运行 Odoo 实例毫无问题。但在生产环境中,Odoo最佳安全实践推荐不要使用数据库超级用户权限的用户来运行生产实例。 Odoo 实例已经运行起来了,现在我们可以通过http://:8069在浏览器中进行访问。这时会出现登录界面,如果不知道主机可以通过 hostname 命令查看或通过 ifconfig 查看 IP 地址。默认管理员的用户名和密码均为 admin。登录后即可看到 Apps菜单,及可安装的应用。 在命令终端中按下Ctrl + C可以停止 Odoo 服务实例并回到命令行。按下上方向键可以回到上一条命令,这样可以通过同样的命令再次快速启动 Odoo。 [image: 1240] 管理 Odoo 数据库 前面我们学习了如何通过命令行创建和初始化 Odoo 数据库。管理数据库还有更多的命令值得我们学习。虽然 Odoo 服务可以自动地进行数据库管理,我们还是可以使用如下命令来手动创建 PostgreSQL 数据库: createdb MyDB 更有趣的是,Odoo 可以通过--template 参数拷贝已有数据库来创建新的数据库。要进行这一操作,被拷贝的数据库不能被连接,所以要确保 Odoo 实例已停止并且没有其它应用连接该数据库。命令如下: createdb --template=MyDB MyDB2 事实上,每当创建数据库时都会使用一个模板,如果没有指定模板,会使用一个名为 template1的预设模板。 要在系统中列出已有数据库,需要使用 PostgreSQL 的 psql 工具及-l 参数: psql -l 执行上述命令会列出我们截至目前所创建的数据库。如果执行了前述操作,可以看到列表中有MyDB和MyDB2。列表中还会显示 每个数据库所使用的编码,默认为UTF-8,这也是 Odoo 所需要的数据库编码。 如需删除数据库,执行dropdb命令: dropdb MyDB2 现在我们已学习了数据库的基本知识。要了解更多 PostgreSQL请参见官方文档或PostgreSQL使用汇总。 **警告:**dropdb操作是不可撤销的,在对重要数据库执行该命令时请务必备份数据库 其它服务器配置项 Odoo 服务还支持一些其它参数,可通过--help 来查看更多参数: ~/odoo-dev/odoo/odoo-bin --help 我们在下面的部分将会学习一些重要参数,首先我们先学习下如何把当前使用参数保存到配置文件中。 Odoo 服务配置文件 大多数的参数都可以保存到配置文件中。默认 Odoo 使用.odoorc文件。Linux 系统中缺省的路径是在家目录($HOME)中,而在 Windows 中则和运行 Odoo 的可执行文件放在同一个目录中。 在老版本的 Odoo/OpenERP 中,默认的配置文件为.openerp-serverrc,为保持向后兼容,存在该文件且没有.odoorc文件的情况下会使用该文件。 一个全新安装中不会自动创建.odoorc配置文件,我们应使用--save参数来保存,如果配置文件不存在则会创建默认配置文件: ~/odoo-dev/odoo/odoo-bin --save --stop-after-init 此处我们还使用--stop-after-init参数以在执行结束后停止服务。这一参数常在运行测试或要求运行模块升级来检测是否正确安装时使用。 小贴士:命令行参数可以缩短到保持不混淆的程度,如--stop-after-init可缩写为--stop。 现在可以通过如下命令来查看缺省配置文件: more ~/.odoorc # 显示配置文件 以上命令会显示所有配置项及配认值,编辑文件后在下一次启动 Odoo 实例后生效,输入 q 回到命令行。 我们还可以使用--conf(或-c)参数来指定配置文件。配置文件无需包含所有配置项,仅包含需修改默认值的配置项即可。 修改监听端口 --http-port=(或-p)参数可以修改实例的监听端口(默认端口8069),不同的端口可以让我们在同一台机器上运行多个实例。 **Odoo 11的修改:**在 Odoo 11中引入--http-port参数以替代此前版本使用的--xmlrpc-port 下面就可以做个尝试,打开两个终端,第一个中输入 ~/odoo-dev/odoo/odoo-bin --http-port=8070 第二个中输入 ~/odoo-dev/odoo/odoo-bin --http-port=8071 此时就在同一台机器上使用不同端口运行了两个 Odoo 实例,这两个实例可以使用同一个数据库或不同数据库。这取决于我们使用的配置参数,并且两个端口上也可以运行相同或不同版本的 Odoo。 **小贴士:**不同 Odoo 版本必须使用不同的数据库。尝试在不同版本上使用相同数据库将无法正常运行,因为各大版本采用了不兼容的数据库模式。 数据库选项 进行 Odoo 开发时,经常会使用多个数据库,有时还会用到不同版本。在同一端口上停止、启动不同服务实例,或在不同数据库间切换,会导致网页客户端会话异常。因为浏览器会存储会话的 Cookie。 在浏览器中使用私有模式访问实例可以避免这一问题。另一优良实践是在服务实例上开启数据库过滤器,这样可以确保实例仅允许对指定数据库的请求,而忽略其它请求。 Odoo 11中的修改: 从Odoo 11开始,--database(或-d)参数可接收逗号分隔的多个数据库名,设置--database参数时也会自动设置--db-filter参数,所以仅有这个数据库才能为服务实例使用。对于 Odoo 11之前的版本,我们需要使用--db-filter来限制可访问的数据库。 --db-filter可限制 Odoo 实例所能使用的数据库。它接收一个正则表达式来过滤可用数据库名,要精确匹配一个名称,表达式需要以^开头并以$结束。例如,仅允许testdb数据库,我们可以使用如下命令: ~/odoo-dev/odoo/odoo-bin --db-filter=^testdb$ 使用--database和--db-filter参数来匹配同一数据库是一个良好的实践。事实上从 Odoo 11开始默认会为--database设置对应的--db-filter。 管理服务器日志消息 --log-level 参数可用于设置日志级别,这有助于了解服务的状况。例如要开始调试日志级别,使用--log-level=debug参数。还有如下选项: debug_sql:查看服务中产生的 SQL 查询 debug_rpc:服务器接收到的请求详情 debug_rpc_answer:服务器发送的响应详情 其实--log-level是设置Odoo 日志级别的简化方式,此外通过更完整的--log-handler参数可以有选择地打开/关闭日志记录器。默认情况下日志会作为标准输出(打印到屏幕),但是可以通过logfile=参数来指定日志存储文件。 安装第三方插件 在 Odoo 实例中产生新的模块并安装,对于初学者总会容易搞不清。下面一起来熟悉这一点。 查找社区模块 网络上有很多 Odoo 模块,Odoo应用商店可以下载一系列模块安装到系统中。另一个重要的资源是Odoo 社区联盟(OCA - Odoo Community Association)维护的模块,可在 GitHub 上查找。OCA 是一个协调社区贡献的非营利组织,它同时提升软件质量,推广最佳开发实践和开源价值观。可通过https://odoo-community.org/来进一步了解 OCA。 为 Odoo 添加模块,仅需将其拷贝到官方插件的 addons 文件夹中即可,按前述安装即为~/odoodev/odoo/addons/。但这不是一个好的实践,我们安装的 Odoo 是由 Git 版本控制的代码仓库,将会与上游 GitHub 仓库保持同步,在其中加入外部插件会不利于管理。 避免这一点,我们可以选取一个或多个存放模块的目录,让 Odoo 服务也会从该目录中查找模块来使用。我们不仅可以把自定义模块放在一个不同的目录下不与官方的混在一起,还可以通过不同目录组织这些模块。 我们可以通过下载系统课程的代码来准备供 Odoo 安装的插件模块,获取 GitHub 上的源码,执行如下命令: cd ~/odoo-dev git clone https://github.com/alanhou/odoo12-development.git library 此时与/odoo同级的/library文件夹中将包含一些模块,现在就需告知 Odoo 这个新的模块目录。 配置插件(add-ons)路径 Odoo 服务有一个addons_path参数可设置查找插件的路径,默认指向Odoo 服务所运行处的/addons文件夹。我们可以指定多个插件目录,这样就可以把自定义模块放到另一个目录下,无需与官方插件混到一起。 通过如下命令可包含新的模块路径来运行服务: cd ~/odoo-dev/odoo ./odoo-bin -d 12-library --addons-path="../library,./addons" 仔细看服务日志,会发现有一行报告插件路径,信息类似INFO ? odoo: addons paths: ,确认下里面是否有library/目录。 使用 Python 虚拟环境安装 Odoo 维护多个 Odoo 版本的代码在 Odoo 开发中很常见,需要整理一下来保持项目在同一台开发机器上并行。改变版本有时会需要上下文的切换。比如,现在 Odoo 的启动执行文件是odoo-bin,而在老版本中是odoo.py。迁移到 Python 3后又更易混淆了,我们要知道是选择python / pip还是python3 / pip3,这取决于使用的 Odoo 版本。 Python 有一个在同机器上管理独立环境的工具virtualenv。每个环境有自己的Python 可执行文件和库文件,仅需在使用时激活环境,然后python和 pip 无需指定就可以在相应的安装了 Python库的环境下运行。要在Debian/Ubuntu上使用virtualenv,执行如下命令: sudo apt install virtualenv 如果我们使用的工作目录是~/odoo-dev,并把 Odoo 12源代码克隆到~/odoo-dev/odoo目录中,我们可以这样进行虚拟环境的创建: virtualenv -p python3 ~/odoo-dev/odoo12env source ~/odoo-dev/odoo12env/bin/activate 一旦激活了虚拟环境,我们可以在其中安装 Odoo,可以通过 pip 来进行操作: pip install -e ~/odoo-dev/odoo 以上代码会将~/odoo-dev/odoo中的 Odoo源代码安装到虚拟环境中。-e 参数非常重要,这是一个可编辑安装。它不会复制一份代码到虚拟环境中,仅仅只是保留了一个到原地址 Odoo 代码的引用。因为使用到了源代码,源代码的修改在当前环境中也同样生效。 Odoo 的 Python 依赖会被自动安装,所以无需使用requirements.txt来进行手动安装。我们也可以通过 pip 来安装其它所需的 Python 库: pip install phonenumbers num2words psycopg2-binary watchdog xlwt 注意我们无需记住使用的是 Python 2还是 Python 3,这里的pip 命令会指向正确的版本。然后就可以运行 Odoo 了,pip 安装创建了一个bin/odoo命令,可在任何位置运行,无需涉及源代码所在目录。 **小贴士:**如果决定使用虚拟环境,任何要使用odoo-bin运行的命令,都可以替换为 odoo 以下命令会启动并关闭所安装版本 Odoo,打印一些日志信息用于确定 Odoo 版本和使用的插件: odoo --stop-after-init 推荐的操作是将配置文件放在虚拟环境文件夹中。以下会为我们的项目初始化一个12-library 数据库,并创建一个对应的12-library.conf 文件: odoo -c ~/odoo-dev/odoo12-env/12-library.conf -d 12-library --addons-path=~/odoo-dev/library,~/odoo-dev/odoo/addons --save --stop 自此开始,我们可通过如下命令启动图书项目 Odoo 服务: odoo -c ~/odoo-dev/odoo12-env/12-library.conf 最后在完成后,通过如下命令来退出环境: deactivate 假设我们要在同一台机器上使用 Odoo 10项目,它使用的是 Python 2.7,通过如下命令创建环境、安装 Odoo: cd ~/odoo-dev git clone https://github.com/odoo/odoo.git -b 10.0 --depth=1 odoo10 virtualenv odoo10env source odoo10env/bin/activate pip install -e ./odoo10 odoo --version deactivate # To finish working with this env. 要使得在 Odoo 版本间切换更容易,我们可以在~/odoo-dev/odoo10目录下再为10.0分支克隆一份源代码。然后创建虚拟环境,激活环境,使用 pip创建一个 Odoo 10可编辑安装。virtualenv没有使用-p 参数指定 Python 版本,默认为 Python 2,也就是 Odoo 10所需的版本。 如果系统中没有 Python 2,Ubuntu 18.04默认就不带 Python 2,则需要执行如下命令来进行安装: sudo apt install python-dev 使用 PyPI 下载和安装插件模块 社区贡献的插件可以打包成 Python 库,发布到 Python 包索引(PyPI -Python Package Index),然后像其它库一样使用 pip 安装。为了能使用这一方法,Odoo 自动添加了site-packages/文件夹至插件配置路径,用于安装库文件。打包可以通过setuptools-odoo工具。 OCA 项目使用该工具打包并发布插件至 PyPI。因不同 Odoo 版本中存在相同模块,模块名之前会加一个 Odoo 版本前缀。例如odoo12-addon-partner-fax 是Odoo 12的partner_fax PyPI 包,它为 partner 添加了一个传真字段。 如需从 PyPI 下载该模块及依赖,并随后安装至odoo12env环境,使用如下命令: source ~/odoo-dev/odoo12env/bin/activate pip install odoo12-addon-partner-fax odoo -c ~/odoo-dev/odoo12-env/12-library.conf -i partner_fax --stop 服务器端开发者模式 为便于开发者,Odoo 有一个--dev=all参数可激活一些开发者友好的功能。 Odoo 10中的修改: --dev=...参数是在 Odoo 10中引入的,它取代了此前版本中更简化、功能也更少的--debug参数 这启用了一些有用的功能可加快开发流程,最重要的如下: 在保存 Python 文件时自动重载 Python 代码,避免手动重启服务 从 XML 中直接读取 view 定义,避免手动升级模块 --dev=all将在抛出异常时启动 Python调试器(pdb),在服务报错后做后验(postmortem)分析非常有益。注意这一设置对日志输出不产生任何影响。有关 Python 调试器命令详情可参见Python 官方文档。 虽然 all 值适用于大多数情况,--dev还可接一串逗号分隔的选项。缺省情况下会使用Python 调试器 pdb。有些人会倾向安装、使用其它调试器,来改善功能和易用性。Odoo 是允许我们指定调试器的,常用的有ipdb和pudb。在本系列第八篇Odoo 12开发之业务逻辑 - 业务流程的支持中,我们将介绍如何在 Odoo 开发中使用调试器。 要自动侦测代码文件的变化 ,服务开发者模式需安装一个额外的依赖python3-watchdog。我们需要在Ubuntu/Debian系统中安装它之后才可使用,命令如下: sudo apt-get install python3-watchdog 对于 Odoo 11之前的版本,使用的是 Python 2,则需安装python-watchdog。同样可使用 pip 安装,命令为pip install watchdog。 总结 在本文中,如们学习了如何在 Ubuntu 系统中安装 Odoo 并从 GitHub 上获取 Odoo源码,以及如何创建Odoo 数据库和运行 Odoo 实例。 现在我们的 Odoo 环境可正常用于开发,并且也可以对数据库和实例进行管理。有了这些,我们可以进行一步的学习了。在下文,我们将从零开始创建第一个 Odoo 模块,并理解相关的主要元素。 ☞☞☞ 接下来请学习Odoo 12 开发之创建第一个 Odoo 应用 本文首发地址:Alan Hou 的个人博客
  • 倡议:参加ODOO平台建模实践

    2
    0 赞同
    2 帖子
    2k 浏览
    Z
    用EXCEL这么强大的吗?非常有兴趣了解。
  • odoo页面隐藏button

    1
    0 赞同
    1 帖子
    939 浏览
    S
    我在界面添加了三个自定义的button,现在我想要去掉自带的创建和导入按钮,但是我在views里面写上create=“false",但是我添加的自定义按钮就显示不出来了,这是我添加自定义按钮的代码: <t t-jquery="button.o_list_button_add" t-operation="append"> <button t-if="widget.modelName == 'tmp_dwtables'" class="appbutton o_find_table_object" type="button">查找表对象</button> <button t-if="widget.modelName == 'tmp_dwtables'" class="appbutton o_find_field_object" type="button">查找字段对象</button> <button t-if="widget.modelName == 'tmp_dwtables'" class="appbutton o_find_proc_object" type="button">查找过程对象</button> <button t-if="widget.modelName == 'tmp_dwproc'" class="appbutton o_find_table_object" type="button">查找表对象</button> <button t-if="widget.modelName == 'tmp_dwproc'" class="appbutton o_find_field_object" type="button">查找字段对象</button> <button t-if="widget.modelName == 'tmp_dwproc'" class="appbutton o_find_proc_object" type="button">查找过程对象</button> <button t-if="widget.modelName == 'tmp_dwfeilds'" class="appbutton o_find_table_object" type="button">查找表对象</button> <button t-if="widget.modelName == 'tmp_dwfeilds'" class="appbutton o_find_field_object" type="button">查找字段对象</button> <button t-if="widget.modelName == 'tmp_dwfeilds'" class="appbutton o_find_proc_object" type="button">查找过程对象</button> </t> 我在三个模型里面,每一个模型显示的页面都增加了三个按钮,我要怎样才能把自带的创建和导入按钮隐藏呢,有没有大佬知道的
  • 0 赞同
    1 帖子
    2k 浏览
    G
    本文地址,格式更美观(持续更新): https://www.sunpop.cn/odoo-12-version-enterprise-community-pricing-support/ odoo收费企业版是对社区版的极大增强,除了增加了很多功能外,最大的区别是企业版对手机支持更好,有单独的APP,同时能提供底层技术支持。下文将进行更详细的描述。 企业版需要购买授权,按年按用户付费,价格上最低5用户全功能约¥5.6万元/年(2019年1月最新报价),一般进销存套装约¥1.2万元/年,制造产销一体套装约¥2.5万元/年。上述算法均不含税。 通过odoo官方合作伙伴(比如我们广州尚鹏)可以有9折折扣,当前增值税算法为16%。 官方购买只提供在线SAAS服务,在线SAAS服务不包含odoo企业版源码。 如果想进行私有云部署,必须通过官方合作伙伴购买。官方合作伙伴会提供完整odoo企业版源码,同时合作伙伴有义务为其客户提供版本升级及配合原生odoo的bug修复,服务期限为一年,包括一年内odoo版本的更新及bug修复。 odoo官方提供一个快速实施服务包。一般合作伙伴也会提供类似的服务包,可参考广州尚鹏官网。这个快速部署包括基础安装、数据导入、定制化、现场服务、咨询顾问等。 官方的版本说明文档在此: https://www.odoo.com/page/editions 官方的价格计算可参考: 官方中文报价 官方服务快速实施服务包 一般进销存套装 [image: ent_price_biz.jpg] 制造产销一体套装 [image: ent_price_mrp.jpg] 官方提供的服务包括(SaaS部署版本) 您可以访问我们的可扩展云基础架构,包括托管、每日增量备份、电子邮件集成, 顶级安全, 24/7 监测和控制中心来管理您的Odoo环境。 Odoo实例升级需求你在你方便的时候,受益于新的功能。 您可以通过电子邮件或应用程序中的在线聊天获得我们的支持。我们的支持团队从周一至周五 24 小时以英语和法语提供服务。 企业版与社区版的详细区别 [image: webp] [image: webp] [image: webp] [image: webp] [image: webp] [image: webp] 以上为不同版本区别,一般都会进行个性化开发。 Odoo Online Success Packs 快速成功服务包 [image: webp] [image: webp] *计算旅行时间;差旅费另行收取。 **仅当“Studio”应用程序包含在订阅中,仅使用“Studio”进行个性化开发。每月将收取额外费用适用于个性化项目的维保。 ***新客户自动享受30%折扣,只适用于他们的第一个服务包(促销截止日期为 2019年02月28日). 关于企业服务的详细说明与常见问题 如果本页面上没有符合您问题的答案,请联系我们 业务QQ 300883. 订阅包括哪些内容? 您可以访问我们的可扩展云基础架构,包括托管、每日增量备份、电子邮件集成, 顶级安全, 24/7 监测和控制中心来管理您的Odoo环境。 Odoo实例升级需求你在你方便的时候,受益于新的功能。 您可以通过电子邮件或应用程序中的在线聊天获得我们的支持。我们的支持团队从周一至周五 24 小时以英语和法语提供服务。 你如何定义付费用户? 将用户定义为在创建和/或编辑模式下访问或将要访问 Odoo 的员工或供应商。外部用户(如作为门户用户的客户或供应商)不计入用户数量。例如: 将报告费用或时间表的员工视为用户; 一个允许合伙伙伴以用户身份在您的Odooo中进行操作; 不会将在线获得发票的客户和供应商视为用户; Odoo网站的游客用户并不会统计在用户数之内。 自助订阅(不包含成功包)包括何种支持? 我们通过电子邮件在标准功能中提供英语版的功能支持和错误修复服务(每周 5 天,每天 24 小时)。 有专门的咨询顾问 成功套件 唯一. 为什么有些应用会自动要求选择其他应用? 有些应用构建于其他应用之上,这意味着这些应用需要其父应用来进行操作。例如,电子商务应用依赖于网站应用。为了激活电子商务应用,您还需要安装网站应用来继承其父功能。 我是否可以轻松地从托管计划(Odoo 在线)切换到企业预置计划(Odoo 企业版)或反向切换? 使用 Odoo 在线时,您可以随时通过控制中心下载数据库的备份。您拥有专属数据! 我们的云基础架构在最新版本的 Odoo 上运行,并定期升级。企业预置版用户必须使用最新稳定版本的 Odoo。如果您想从 Odoo 在线切换到 Odoo 企业预置版,在最新稳定版本发布之后,立即进行此更改为佳。 如果您的本地数据库使用最新的稳定版本,Odoo 还提供一项服务来帮助您从 Odoo 企业预置版免费切换到 Odoo 在线。关于更多的详细信息或问题,请随时与我们联系。 联系我们. 我如何选择正确的实施服务成功包? 填写以上表格,页面将根据您的需求为您提供最好的成功包。根据我们对过往项目的经验,我们将推荐合适的业务包,以便 80% 的客户只需一个成功包就可以成功地为所需的范围部署 Odoo。 客户在最初实施时购买额外的成功包最常见的原因是数据导入问题(由于无序的合并数据或异常大量的数据导入)、不必要的定制(导致更长的前置期)或在完成实施之前需要额外对员工进行培训。 有些客户也可能会选择在实施后购买额外的成功包,因为他们希望解决方案随着公司的发展和时间的推移逐渐发展(支持时间永不过期)。 我可以为我的网站使用自己的域名吗? 当然!我们的支持团队能够在实施过程中为您提供指导,以便根据您计划使用相同域名管理电子邮件的方法,使用 Odoo 来设置您的域名。 没有在这个页面上列出的应用程序的价格是多少? Odoo 中的一些应用程序是免费提供的,如调查问卷、讨论、便签、聊天和员工。有些应用捆绑在其他应用之中,如博客、论坛、在线聊天和幻灯片捆绑在网站应用之中,不会显示在此页面上。 为什么云端和 On Premise 提供的产品是同样的价格? 维护一个Odoo 执行的真实成本并非托管成本(我营业额的1%),而是关于维护服务的人力成本:支援、升级、调配、维护电邮/备份/数据库服务台。 尽管为了托管云端客户令我们有额外的服务器成本,这些客户并没有电邮配置问题,并且一直使用最新版本,没有升级困难等等。 所以,尽管听起来是相矛盾的,对于我们来说维护一个云端客户比起维护一名“On Premise"客户所需的钱更少。因为云端客户通常会有更好的体验(只需在一个精调的基础建设上点击几下),我们决定提供免费托管。 免费提供可以免费多长时间? 永远免费提供,无限量的用家,只要您不安装额外的应用程式。 关于服务包的详细说明与常见问题 快速服务包包括什么? 包括由专门顾问提供的高级服务包。在实施阶段,您将有一个Odoo项目经理分配给您来分析您的需求,并根据您的需求配置您的Odoo应用程序。该顾问还将培训您如何使用Odoo应用程序,指导您如何使用Odoo的功能和功能来发展您的业务。他还将定制您的Odoo应用程序,只要您选择了“定制应用程序”。根据您在定价页面上选择的应用程序和自定义应用程序的数量,将预先选择最适合成功开始使用Odoo所需的典型小时数的包。我们的顾问将尽他们最大的努力帮助您。 “专业的客户成功顾问”会做什么? 在实施之前,我们的顾问将分析您的业务运行方式,并建议使用Odoo的最佳方式。我们将处理所有配置并指导您如何使用Odoo。这项服务是通过有计划的会议(通过电话或在线)组织的,我们的顾问将对您的需求进行更深入的分析,看看在现有的功能可能性的官方Odoo应用程序可以改进什么。我们将为您提供培训材料,使您始终能够使用最新版本的Odoo应用程序。 如果我有需要开发和特别集成的定制需求,该怎么办? 对于高级需求,如定制开发,您可以与我们或官方的Odoo合作伙伴一起工作。我们的官方合作伙伴提供项目管理服务、Odoo开发、培训以及内部安装和集成服务。我们所进行的开发每天收取咨询费。合作伙伴通常对他们每天的咨询或开发服务收费。 如果本页面上没有符合您问题的答案,请联系我们
  • odoo12 使用controller返回视图

    1
    0 赞同
    1 帖子
    1k 浏览
    S
    我有一部分代码,我需要在controller里面去做一些处理,然后再通过http来返回其中一个模型的视图。我使用了http.redirect_with_hash这个方法,具体代码: return http.redirect_with_hash('http://127.0.0.1:8069/web#action=doms.act_tmp_dwtables_list') 这样可以转到action对应的视图,但是视图的标题栏上面的按钮都没有了,大家有知道这该怎样处理的吗,或者我该使用其他的方法函数??