开启/关闭Odoo服务器
Odoo使用客户端/服务器体系结构,客户端是通过RPC访问Odoo 服务器的Web浏览器。
业务逻辑和扩展通常在服务器端执行,尽管支持客户端特征(例如像交互式地图的新数据表示)可以添加到客户端。
为了启动服务器,只需调用shell中的命令Odoo-bin,必要时将完整路径添加到文件中:
odoo-bin
服务器通过从终端点击Ctrl-C两次或杀死相应的OS进程而停止。
服务器和客户端扩展都被打包为可选地加载在数据库中的模块。
Odoo模块可以向Odoo系统添加全新的业务逻辑,或者更改和扩展现有业务逻辑:可以创建一个模块来将国家的会计规则添加到Odoo的通用会计支持中,而下一个模块则为公共汽车车队的实时可视化提供支持。
因此,Odoo中的一切都以模块开始和结束。
Odoo模块可以包含多个元素:
业务对象
声明为Python类,这些资源将根据Odoo的配置自动持久
数据文件
XML或CSV文件声明元数据(视图或工作流)、配置数据(模块参数化)、演示数据等
网络控制器
处理来自Web浏览器的请求
静态Web数据
Web界面或网站使用的图像、CSS或JavaScript文件
每个模块是模块目录内的目录。模块目录通过--addons-path
选项指定。
提示
大多数命令行选项也可以使用配置文件来设置
通过它的清单声明一个Odoo模块。 请参阅有关它的清单文档。
一个模块也是一个带有__init__.py文件的Python包,包含模块中各种Python文件的导入指令。
例如,如果模块有一个单独的mymodule.py文件,__init__.py可能包含:
from . import mymodule
Odoo提供了一种帮助建立一个新模块的机制,odoo-bin有一个子命令scaffold来创建一个空模块:
$ odoo-bin scaffold
该命令为您的模块创建子目录,并自动为模块创建一系列标准文件。它们中的大多数只包含注释代码或XML。大多数这些文件的用法将在本教程中说明。(译者注:在进入从github上下载的odoo根目录后,执行上面的命令,需要在odoo-bin前面使用python命令)
练习
模块创建
使用上面的命令行创建一个空模块Open Academy,并将其安装在Odoo。
odoo-bin scaffold openacademy myaddons
。[3]openacademy/__manifest__.py
# -*- coding: utf-8 -*-
{
'name': "Open Academy",
'summary': """Manage trainings""",
'description': """
Open Academy module for managing trainings:
- training courses
- training sessions
- attendees registration
""",
'author': "My Company",
'website': "http://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml
# for the full list
'category': 'Test',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
# always loaded
'data': [
# 'security/ir.model.access.csv',
'templates.xml',
],
# only loaded in demonstration mode
'demo': [
'demo.xml',
],
}
openacademy/__init__.py
# -*- coding: utf-8 -*-
from . import controllers
from . import models
openacademy/controllers.py
# -*- coding: utf-8 -*-
from odoo import http
# class Openacademy(http.Controller):
# @http.route('/openacademy/openacademy/', auth='public')
# def index(self, **kw):
# return "Hello, world"
# @http.route('/openacademy/openacademy/objects/', auth='public')
# def list(self, **kw):
# return http.request.render('openacademy.listing', {
# 'root': '/openacademy/openacademy',
# 'objects': http.request.env['openacademy.openacademy'].search([]),
# })
# @http.route('/openacademy/openacademy/objects//', auth='public')
# def object(self, obj, **kw):
# return http.request.render('openacademy.object', {
# 'object': obj
# })
openacademy/demo.xml
openacademy/models.py
# -*- coding: utf-8 -*-
from odoo import models, fields, api
# class openacademy(models.Model):
# _name = 'openacademy.openacademy'
# name = fields.Char()
openacademy/security/ir.model.access.csv
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_openacademy_openacademy,openacademy.openacademy,model_openacademy_openacademy,,1,0,0,0
openacademy/templates.xml
Odoo的一个关键组件是ORM层。这一层避免了手工编写大多数SQL并提供可扩展性和安全性服务[2]。
业务对象被声明为扩展了Model
的Python类,这些类将它们集成到自动持久化系统中。
模型可以通过在其定义中设置多个属性来配置。最重要的属性是_name
,它需要在Odoo系统中定义模型的名称。这里是一个模型的最小完整定义:
from odoo import models
class MinimalModel(models.Model):
_name = 'test.model'
字段用于定义模型可以存储的内容和位置。字段定义为模型类的属性:
from odoo import models, fields
class LessMinimalModel(models.Model):
_name = 'test.model2'
name = fields.Char()
共同属性
与模型本身非常相似,可以通过将配置属性作为参数来配置其字段:
name = field.Char(required=True)
某些属性在所有字段都可用,这里是最常见的属性:
string
(unicode
, 默认的: 字段的name)
UI中字段的标签(用户可见)
required
(bool
, 默认的: False
)
如果True,字段不能为空,则它必须具有默认值,或者在创建记录时总是被赋予一个值
help
(unicode
, 默认的: ''
)
长的表单,为UI中的用户提供帮助工具提示
index
(bool
, 默认的: False
)
请求Odoo在列上创建数据库索引
简单字段
字段有两大类:“简单”字段,这些字段是直接存储在模型表中的原子值和链接记录(同一模型或不同模型)的“关系”字段。
简单字段示例是 Boolean
, Date
, Char
保留字段
Odoo在所有模型[1]中创建了几个字段。这些字段由系统管理,不应写入。如果有用或必要,它们可以被读取:
id
(Id
)
模型中记录的唯一标识
create_date
(Datetime
)
记录的创建日期
create_uid
(Many2one
)
创建记录的用户
write_date
(Datetime
)
记录的最后修改日期
write_uid
(Many2one
)
上次修改记录的用户
特殊字段
默认情况下,Odoo还需要所有模型上的name
字段,这是为了所有显示和搜索行为。用于这些目的的字段可以通过设置_rec_name
来重写。
练习
定义一个模型
在openacademy 模块中定义一个新的数据模型Course。课程有标题和描述。课程必须有标题。
编辑文件 openacademy/models/models.py
以包含一个Course类。
openacademy/models.py
from odoo import models, fields, api
class Course(models.Model):
_name = 'openacademy.course'
name = fields.Char(string="Title", required=True)
description = fields.Text()
Odoo是一个高度数据驱动的系统。虽然使用Python代码定制行为,但模块的值的一部分是在数据中的并在加载时设置。
提示
有些模块只存在于Odoo中添加数据
模块数据是通过数据文件、带有
{a value}
model
是记录的Odoo模型的名称id
是一个外部标识符,它允许引用记录(而不必知道它的数据库标识符)
元素具有一个 name
,其是模型中的字段的名称(例如description
)。它们的内容是字段的值数据文件必须在要加载的清单文件中声明,它们可以在'data'列表(总是加载)或'demo'列表中声明(仅加载在演示模式中)。
练习
定义演示数据
创建示范性数据填充带有一些示范课程的Courses 模型。
编辑文件 openacademy/demo/demo.xml
以包含某些数据。
openacademy/demo.xml
Course 0
Course 0's description
Can have multiple lines
Course 1
Course 2
Course 2's description
动作和菜单是数据库中的常规记录,通常通过数据文件声明。动作可以通过三种方式触发:
因为菜单有一些复杂的声明,所以有一个快捷方式来声明ir.ui.menu并更容易地将它连接到相应的动作。
Ideas
idea.idea
tree,form
危险
必须在XML文件中的相应菜单之前声明该动作。
数据文件按顺序执行,在创建菜单之前,动作id必须存在于数据库中。
练习
定义新的菜单条目
定义新菜单项以访问OpenAcademy 菜单项下的课程。用户应该能够:
data
列表中openacademy/__manifest__.py
'data': [
# 'security/ir.model.access.csv',
'templates.xml',
'views/openacademy.xml',
],
# only loaded in demonstration mode
'demo': [
openacademy/views/openacademy.xml
Courses
openacademy.course
form
tree,form
Create the first course
视图定义模型的记录显示方式。每种类型的视图代表可视化的模式(记录列表,它们的聚合图,…)。一般情况下,视图可以通过它们的类型(例如合作伙伴的列表)或具体地通过它们的id来请求。对于通用请求,将使用具有正确类型和最低优先级的视图(因此,每种类型的最低优先级视图是该类型的默认视图)。
视图继承允许更改在别处声明的视图(添加或删除内容)。
视图被声明为模型ir.ui.view的记录。视图类型由arch
字段的根元素暗示:
view.name
object_name
危险
视图的内容是XML。
因此,必须将arch
字段声明为正确解析的type="xml"
树视图,也称为列表视图,以表格形式显示记录。
它们的根元素是
。树视图的最简单形式只列出表中显示的所有字段(每个字段作为列):
表单用于创建和编辑单个记录。
它们的根元素是。它们由高级结构元素(groups、notebooks)和交互元素(buttons 和fields)组成:
练习
使用XML定制表单视图。
为Course对象创建自己的表单视图。显示的数据应该是:课程name和description。
openacademy/views/openacademy.xml
course.form
openacademy.course