zoukankan      html  css  js  c++  java
  • 【odoo14】【好书学习】第三章、创建插件

    老韩头的开发日常【好书学习】系列

    现在我们已经有了开发环境并了解了如何管理实例及数据库,现在让我们来学习下如何创建插件模块。
    本章内容如下:

    • 创建和安装模块
    • 完成manifest文件
    • 组织模块文件结构
    • 添加模型
    • 添加菜单及视图
    • 添加访问控制
    • 使用scaffold命令创建模型

    在odoo中什么是模块(add-on module)?

    除了框架代码,其他的代码都是以模块的形式组织起来的。这些模块可以随时安装和卸载。由于odoo用于各种规模的公司,每一个公司都有自己的业务流程。为了解决这一个问题,应用将应用拆分到不同的模块当中。这些模块在需要的时候才会被载入。我们可以随时启停这些功能。同一个应用也可以适配不同的需求。如下截图当中是以不同的应用分组,每一组第一个应用是主模块,其余的是属于其辅助模块。

    在创建应用时应该创建各个功能的边界。这将非常有助于将应用程序划分为不同的附加模块。下面让我们开始构建自己的附加模块了。

    创建和安装新应用

    准备

    在用的odoo实例

    步骤

    作为例子,我们这一章将创建一个管理图书的模块。

    1. 进入项目工程,创建本地目录。
    $ cd ~/odoo-dev
    $ mkdir local-addons
    
    1. 创建项目目录
    $ mkdir local-addons/my_library
    
    1. 创建__init__.py文件
    $ touch local-addons/my_library/__init__.py
    
    1. 创建__manifest__.py文件,并写入
    {'name': 'My Library'}
    
    1. 将本地目录配置到odoo路径中。
    $ odoo/odoo-bin --addons-path=odoo/addon/,local-addons/
    

    如果我们在命令行中使用--save,那么相应的配置会存储的配置文件下次使用的时候就会更方便了。
    6. 通过在APP页面刷新本地目录按钮,可以在列表当中查看到我们新建的项目。

    1. 安装

    原理

    odoo模块是包含着源代码及其他文件的目录。该文件夹名称通常是模块的技术名称。
    manifest.py是Python的字典包含着模块儿的相关信息。
    模块必须是可导入的,也就是说它必须具备__init__.py文件,即使这个文件时空的。

    完成模块的__manifest__.py文件

    准备

    上一节内容

    步骤

    1. 编辑__manifest__.py文件
    'name': "My library",
    'summary': "Manage books easily",
    'description': """
    Manage Library
    ==============
    Description related to library.
    """,
    'author': "Your name",
    'website': "http://www.example.com",
    'category': 'Uncategorized',
    'version': '13.0.1',
    'depends': ['base'],
    'data': ['views/views.xml'],
    'demo': ['demo.xml'],
    }
    
    1. 为模块选择一个icon图标,放置在static/description/icon.png中。

    原理

    • name: 模块的名称。
    • summary: 模块的简单介绍。
    • description: 模块的长介绍。通常是纯文本或者ReStructuredText (RST) 格式。
    • author: 模块作者。
    • website: 模块开发者的网站。
    • category: 模块的分类。关于模块分类有一个标准的列表可供选择( https://github.com/odoo/ odoo/blob/13.0/odoo/addons/base/data/ir_module_category_ data.xml. )。当然你也可以定义自己的名称。
    • version: 模块的版本。这通常用于odoo检测是否有新的版本需要升级。如果所输入的版本当中并不包含包含odoo的主版本(12.0,13.0,14.0),odoo将自动添加。
    • depends: 这是当前模块所依赖的其他模块。即便模块不依赖于其他的模块儿的话,要么也应该输入base模块。在填写依赖的时候应注意依赖的顺序。
    • data: 这是数据文件的列表。数据文件的路径是相对于模块的根路径的通常是xml及csv文件。也可以是yaml文件,这在第六章进行介绍。
    • demo: 这关联模块儿的演示数据。
      由于odoo主版本之间存在蛮多的不同一个模块儿,可能并不是用于其他的版本。

    更多

    在__manifest__.py的description中,也可以是单独的描述性文件。自odoo8之后,支持README文件或者其他的txt、rst、md扩展名的文件。或者直接展示在description/index.html的内容。
    html文件将直接复写描述中的内容。
    还有几个关键的key

    • licence: 默认是LGPL-3协议。
    • application: True/False,当前模块是否是核心模块。
    • auto_install: True/False,代表是否在其所依赖的模块完成安装后自动安装。
    • installable: True/False,代表当前模块是否可安装。
    • external_dependencies: 一些模块可能依赖于Python或bin包。如果当前环境不具备,这些内容那么安装将停止。
    • {pre_init, post_init, uninstall}_hook: 这里代表python的函数,分别是安装前,安装后,卸载时运行(详细将在第八章介绍)
      还有几个特殊的key
    • price: 代表当前模块儿的售价,如果没有设置的话,那么代表免费。
    • currency: 代表当前模块儿售价的单位。默认是EUR。
    • live_test_url: 表示在线试用的链接。
    • iap: 如果模块提供IAP服务,请填写IAP的key。
    • images: images的路径,这些图片用于在odoo的app商城上展示。

    组织模块文件结构

    模块当中包含源代码及其他各种各样的文件,虽然我们可以随便放置,但是建议还是按照模块的结构进行规范化。

    准备

    假定我们的模块位于local-addons/my_ library,并包含了__manifest__.py,__init__.py文件。

    1. 创建目录及文件
    $ cd local-addons/my_library
    $ mkdir models
    $ touch models/__init__.py
    $ mkdir controllers
    $ touch controllers/__init__.py
    $ mkdir views
    $ touch views/views.xml
    $ mkdir security
    $ mkdir wizard
    $ touch wizard/__init__.py
    $ mkdir report
    $ mkdir data
    $ mkdir demo
    $ mkdir i18n
    
    1. 编辑__init__.py文件
    from . import models
    from . import controllers
    from . import wizard
    

    大部分目录结构式如下

    my_library
    ├── __init__.py
    ├── __manifest__.py
    ├── controllers
    │ └── __init__.py
    ├── data
    ├── demo
    ├── i18n
    ├── models
    │ └── __init__.py
    ├── security
    ├── static
    │   ├── description
    │ └── src
    │ ├─ js
    │ ├─ scss
    │ ├─ css
    │ └ xml
    ├── report
    ├── wizard
    │ └── __init__.py
    └──views
    └── __init__.py
    

    原理

    odoo中主要有三种类型的文件

    • Python: .py文件,包含模型对象、业务逻辑
    • Data文件: 定义在data及demo的key中。通常是XML及CSV文件。YAML文件也可以,他可以在模块加载的时候执行一些指令。对于实例而言,相较于xml的静态更新,yaml可以实现动态生成和更新记录。
    • Web assets是JavaScript、CSS、SCSS及QWeb/HTML模板的集合。这些文件通常用于构建友爱页面以及管理用户的点击行为。还有一些被定义为XML的文件,去扩成主模板的功能。

    模块文件通过如下方式进行组织:

    • models/: 包含模块的模型对象定义及其业务逻辑。详见第四章应用模型
    • views/: 包含定义用户交互的xml文件。包括动作、form视图、list视图等。建议每一个模型都有单独的xml文件。网站模板的文件名建议以_template后缀。后端视图将在第九章后端视图介绍,网站视图将在第十四章CMS开发介绍。
    • data/: 包含模型的初始化数据。将在第六章管理模块数据介绍。
    • demo/: 包含演示数据,用于测试。
    • il8n/: 用于存放翻译文件。以.pot及.po文件为主。将在第十一章,国际化中进行介绍。
    • security/: 包含权限控制的相关文件。包括ir.model.access.csv,xml文件(定义权限组及记录规则信息)。详见第十章权限控制。
    • controllers/: 包含web网站的访问定义等业务逻辑。详见第十三章,web服务开发。
    • static/: 网站相关的定义文件。这里的文件是允许非登录用户访问的。主要包括JavaScript、样式文件及images。这并不需要在manifest中引用,但需要在web模板中引用。详见第十四章,CMS开发。
    • wizard/: 包含向导相关的文件。在odoo中,wizard用于保存中间数据。详见第八章,服务端开发-进阶。
    • report/: odoo提供了生成pdf文件的特性。这里将用于生成的pdf报告的相关文件。详见第十二章,自动化、流程、邮件及打印。

    当我们添加了新的文件后,不要忘记在__manifest__.py及__init__.py中进行引用。

    添加模型

    模型定了我们业务逻辑中的数据结构。
    在这一章节当中,我们将添加图书模型。

    准备

    步骤

    1. 添加模型文件models/library_book.py
    from odoo import models, fields
    class LibraryBook(models.Model):
    _name = 'library.book'
    name = fields.Char('Title', required=True)
    date_release = fields.Date('Release Date')
    author_ids = fields.Many2many(
    'res.partner',
    string='Authors'
    )
    
    1. 将新增文件添加到models/init.py
    from . import library_book
    
    1. 编辑模块的初始化文件__init__.py
    from . import models
    
    1. 通过页面UI或者命令行更新模块
      现在模型已添加到数据库中了。可通过两种方式查看:
    2. 通过odoo的页面,在菜单 Settings|Technical|Database Structure|models下查找目标模型。
    3. 进入数据库查看
    $ psql test-13.0
    test-13.0# d library_book;
    

    原理

    odoo中有自己的的Object Relations Mapping(ORM)框架。orm框架提供了对postgresql数据库的抽象。通过继承odoo的python类model,我们能够创建自己的模型。
    模型有几个通用的以_为前缀的属性。最重要的是_name,它是模型的唯一标识。ORM框架生成数据库表也是基于这个属性。数据库表明是将name中的”.“替换为”_“。
    我们新增了模型文件后,需要将其添加到同目录的__init__.py文件中。

    添加菜单及视图

    这节我们将实现页面菜单及视图的展示。

    准备

    步骤

    菜单和视图都是以xml文件的形式存在。

    1. 创建xml文件以添加数据记录,views/library_book.xml
    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
    <!-- Data records go here -->
    </odoo>
    
    1. 将新增的xml文件添加到__manifest__.py文件中
    {
    'name': "My Library",
    'summary': "Manage books easily",
    'depends': ['base'],
    'data': ['views/library_book.xml'],
    }
    
    1. 在library_book.xml中添加动作action(用于打开视图)
    <record id='library_book_action' model='ir.actions.act_ window'>
    <field name="name">Library Books</field>
    <field name="res_model">library.book</field>
    <field name="view_mode">tree,form</field>
    </record>
    
    1. 添加菜单,并将action关联到菜单上
    <menuitem name="My Library" id="library_base_menu" />
    <menuitem name="Books" id="library_book_menu" parent="library_base_menu" action="library_book_action"/>
    
    1. 在library_book.xml中添加form视图
    <record id="library_book_view_form" model="ir.ui.view">
    	<field name="name">Library Book Form</field>
    	<field name="model">library.book</field>
    	<field name="arch" type="xml">
    	<form>
    		<group>
    			<group>
    				<field name="name"/>
    				<field name="author_ids" widget="many2many_tags"/>
    			</group>
    			<group>
    				<field name="date_release"/>
    			</group>
    		</group>
    	</form>
    	</field>
    </record>
    
    1. 添加tree(list)列表视图
    <record id="library_book_view_tree" model="ir.ui.view">
    	<field name="name">Library Book List</field>
    	<field name="model">library.book</field>
    	<field name="arch" type="xml">
    		<tree>
    			<field name="name"/>
    			<field name="date_release"/>
    		</tree>
    	</field>
    </record>
    
    1. 添加搜索视图
    <record id="library_book_view_search" model="ir.ui.view">
    	<field name="name">Library Book Search</field>
    	<field name="model">library.book</field>
    	<field name="arch" type="xml">
    		<search>
    			<field name="name"/>
    			<field name="author_ids"/>
    			<filter string="No Authors"
    			name="without_author"
    			domain="[('author_ids','=',False)]"/>
    		</search>
    	</field>
    </record>
    
    1. 当一个新的模型添加到odoo中后,默认是没有访问权限的,这样菜单及视图也是看不到的。我们可以通过进入超级管理员模式去查看相关内容。

    进入超级管理员模式

    进入管理员模式后,右上角视图将变成

    原理

    数据文件可以放在模块目录中的任何位置,但约定是在视图/子目录中定义用户界面。通常,这些文件的名称基于模型的名称。在本例中,我们正在为图书馆.book模型,所以我们创建了 views/library_book.xml文件。
    下一步是定义一个窗口操作。动作操作的目标模型定义在res_model中,name属性用于在用户打开动作时向用户显示标题。这些只是基本属性。窗口操作支持附加属性,从而可以更有效地控制视图的呈现方式,例如显示哪些视图、在可用记录上添加过滤器或设置默认值。在第9章后端视图中详细讨论了这些问题。
    通常,数据记录是使用标记定义的,并将记录添加到模型ir.actions.action_window的数据库表中。
    相似,菜单是添加到ir.ui.menu模型中。我们也可以使用的简化标签。
    下面是菜单的主要属性:

    • name: 菜单展示的内容
    • action: 点击菜单后出发的动作
    • sequence: 菜单的展示顺序
    • parent: 代表当前菜单所属的父级菜单
    • web_icon: 标识显示在菜单上的icon图标。这个只在企业版生效。
      截止目前,我们还没有添加视图。但是如果我们更新模块,那么odoo将自动创建默认的视图。
      所有的视图都是定义在ir.ui.view模型中的。主要属性如下:
    • name: 视图的标题。如果没写,odoo将视同模型的名称及视图的类型自动生成一个。
    • model: 这是视图所属的模型。
    • arch: 这是视图的架构。
      Form视图是定义在
      元素中的,通过进行组织展示的元素。
      Tree视图定义在,Search视图定义在

    添加访问控制

    在我们的前面提到的model、view、menu都涉及到权限控制。
    在odoo中,权限是以组的形式展开的。用户属于某些权限组,通过对权限组进行授权实现对model、view、menu的控制。

    准备

    步骤

    1. 权限组,security/groups.xml
    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
    <record id="group_librarian" model="res.groups">
    <field name="name">Librarians</field>
    <field name="users" eval="[(4, ref('base.user_ admin'))]"/>
    </record>
    </odoo>
    
    1. 通过security/ir.model.access.csv进行模型权限的配置
    id,name,model_id:id,group_id:id,perm_read,perm_ write,perm_create,perm_unlink
    acl_book,library.book default,model_library_book,,1,0,0,0
    acl_book_librarian,library.book_librarian,model_library_ book,group_librarian,1,1,1,1
    
    1. 将以上文件添加到__manifest__.py中
    # ...
    'data': [
    'security/groups.xml',
    'security/ir.model.access.csv',
    'views/library_book.xml'
    ],
    # ...
    

    原理

    以上我们涉及了权限组的创建及对权限组进行模型授权

    • security/groups.xml,定义了权限组,id为权限组的唯一标识,name是权限组的名称,users是权限组初始化时包含的用户。其实groups也是将权限组的记录写入res.groups模型中。
    • ir.model.access.csv文件,定义了权限组对于模型的访问权限。其实就是将csv中的信息写入ir.model.access模型中。

    使用scaffold命令创建模型

    之前我们自己构建了模块的结构,但是其实odoo提供了简单构建模块的命令: scaffold。

    准备

    步骤

    1. 进入本地模块所在目录,如下:
    $ cd ~/odoo-dev/local-addons
    
    1. 通过命令创建模块, scaffold 模块的技术名称
    $ ~/odoo-dev/odoo/odoo-bin scaffold my_module
    
    1. 如下是命令自动创建的模块架构
    $ tree my_module
    my_module/
    ├── __init__.py
    ├── __manifest__.py
    ├── controllers
    │ 	├── __init__.py
    │ 	└── controllers.py
    ├── demo
    │ 	└── demo.xml
    ├── models
    │ 	├── __init__.py
    │ 	└── models.py
    ├── security
    │ 	└── ir.model.access.csv
    └── views
    	├── templates.xml
    	└── views.xml
    5 directories, 10 files
    

    原理

    scaffold是基于模板创建新模块的。
    默认是创建在当前目录下,也可指定存储的目录。

     $ ~/odoo-dev/odoo/odoo-bin scaffold my_module ~/odoo-dev/local- addons
    

    odoo中是有两个模板的,处于/odoo/cli/templates目录中。一个是默认的模板,另一个主要用于网站主题。当然我们也可以使用我们自己的模板。通过-t指定模板存储的路径。

     $ ~/odoo-dev/odoo/odoo-bin scaffold -t path/to/template my_ module
    

    本文来自博客园,作者:老韩头的开发日常,转载请注明原文链接:https://www.cnblogs.com/xushuotec/p/14443536.html

  • 相关阅读:
    笔记本搜不到无线网络连接[转]
    局域网IP冲突
    CFree 修改/添加编译配置环境(Build Configuration)
    字母索引网页
    NAOChoregraphe"单机使用许可证使用了多次"问题解决方案
    redis源码笔记-dict.c
    redis源码笔记-sds
    redis源码笔记-testhelp
    redis源码笔记-endian
    redis源码笔记-dict.h
  • 原文地址:https://www.cnblogs.com/xushuotec/p/14443536.html
Copyright © 2011-2022 走看看