原网站:https://www.odoo.com/documentation/9.0/howtos/backend.html#start-stop-the-odoo-server
-
启动/停止Odoo服务器
odoo运用了客户端/服务器的结构模式,在这种模式下,客户端就是通过RPC链接Odoo的浏览器。
Business logic and extension is generally performed on the server side,although supporting client features (e.g. new data representation such asinteractive maps) can be added to the client.
在shell中借助命令odoo.py来启动服务器,如果必要的花添加完整的路径至文件。
通过在终端按两下CTRL+C或者结束相应的OS进程来停止服务器。
-
创建一个Odoo模块
服务器和客户端的扩展都是打包成模块来装载在数据库中。
Odoo模块不仅能添加新的业务逻辑分支到Odoo系统,而且能够修改或者扩展现有的业务逻辑:一个模块被创建后能够添加你自己国家的会计规则到Odoo的一般的会计支持中,while thenext module adds support for real-time visualisation of a bus fleet.
任何事情在Odoo中都是始于模块止于模块的。
模块的配置
一个Odoo模块能够包含一系列的元素:
业务对象
这些基于配置的,声明为Python对象的资源能够被Odoo自动支持。
数据文件
XML或CSV文件,声明metadata元数据(views和workflow),配置文件数据(模块参数)和demonstration data等。
Web控制器
处理来自浏览器的请求。
静态Web数据
网站或者Web接口要用到的图片,CSS样式或JS文件。
模块结构
每个模块都是一个包含模块目录的目录。通过--addons-path的设置来指定模块目录。
通过manifest来声明一个Odoo模块。See the manifest documentation informationabout it.
一个模块同时也是一个Python package with a __init__.py文件,包含了对模块里各个Python文件的介绍。
例如,如果模块只包含了mymoudle.py文件,那么__init__.py文件可能包含:
from . import mymoduleOdoo提供了帮助创建新模块的一个功能, odoo.py 有一个子命令 scaffold to create an empty module:$ odoo.py scaffold <module name> <where to put it>
这个命令为你的模块创建一个子目录并且自动的创建了一系列标准化的文件。大部分只简单的包含了注释代码或者XML。The usage of most of those files will be explained along this tutorial.
对象关系映射
ORM层是Odoo的一个关键组件。该层避免了手写SQL的必要性,并且提供了延展性和安全性。
业务对象被声明为Python对象且继承了Model,将其整合进自动化的持久化系统。
通过在定义model时set一系列的属性来配置model。_name是最重要的属性,它是必须的,而且为Odoo系统中的model定义了名称。Here is a minimally complete definition of amodel:
from openerp import models class MinimalModel(models.Model): _name = 'test.model'
模型Fields
fields通常用来定义模型能存储的东西和位置。fields在model类中被定义为attributes:
from openerp import models, fields class LessMinimalModel(models.Model): _name = 'test.model2' name = fields.Char()
普通field
和model本身一样,他的field可以通过把属性作为参数来配置:
name = field.Char(required=True)一些属性在所有fields中都是可用的,here are the most common ones:
string
(unicode
, default: field's name)- The label of the field in UI (visible by users).
required
(bool
, default:False
)- If
True
, the field can not be empty, it must either have a defaultvalue or always be given a value when creating a record.help
(unicode
, default:''
)- Long-form, provides a help tooltip to users in the UI.
index
(bool
, default:False
)- Requests that Odoo create a database index on the column
简单field
两大类字段:”simple“ field是一些atomic values直接存储在模型的table中。”relational“ field linking records (相同或不同的models)
simple field:Boolean,Date,Char
保留field
Odoo在all model中创建了一些fields。这些fields由系统管理且不能被写入,在必要或有用的情况下能够被read:
id
(Id
)- the unique identifier for a record in its model
create_date
(Datetime
)- creation date of the record
create_uid
(Many2one
)- user who created the record
write_date
(Datetime
)- last modification date of the record
write_uid
(Many2one
)- user who last modified the record
特殊field
通常来说,Odoo中所有的model需要一个name字段,以便用户各样的显示和搜索。通过setting
_rec_name
能够重写这个字段。ORM API:https://www.odoo.com/documentation/9.0/reference/orm.html#recordsets
数据文件
Odoo is a highly data driven system.Although behavior is customized usingPython code part of a module's value is in the data it sets up when loaded.
模块数据通过data files被声明,XML文件,with
<record>
元素。每个<record>
都创建或者更新一条数据库记录。
<openerp> <data> <record model="{model name}" id="{record identifier}"> <field name="{a field name}">{a value}</field> </record> </data> </openerp>
model
is the name of the Odoo model for the record。这条记录所对应的Odoo model的名称。
id 是一个外部标识符(external identifier),他能够关系record(without having to know its in-database identifier)
<field>
elements have aname
which is the name of the field in themodel (e.g.description
). Their body is the field's value.
Data files必须通过manifest文件来声明才能被加载,他们能够在data(总是加载) 或 demo (只在演示数据模式下加载)中被声明。
Action和菜单
Actions和菜单在数据库中是有规律的记录,通常通过data file来声明。Actions能够在3种情况下被触发:
1.点击menu items(linked to specific actions)
2.通过点击views上的button(if these are connected to actions)
因为菜单的声明有点复杂,所以现有一个<menutiem>来简单的声明
ir.ui.menu
,且更加方便的链接他所对应的action。<record model="ir.actions.act_window" id="action_list_ideas"> <field name="name">Ideas</field> <field name="res_model">idea.idea</field> <field name="view_mode">tree,form</field> </record> <menuitem id="menu_ideas" parent="menu_root" name="Ideas" sequence="10" action="action_list_ideas"/>注意:action必须在他在XML文件里关联菜单前被声明。data files是顺序的被执行,action的id必须在数据库中被赋予,在菜单创建之前。
Basic views
views定义了model的记录展示的方式。每种view都表示一种形象化的模式(一系列的记录,记录统计的图表)。views一般能够被它同类型的来请求(例如list of parnters)或者通过他们的id来请求。对于一般的请求来说,有着correct类型的view和最低优先级的view会被使用(所以每种类型的最低优先级的view是该中类型的默认view)。
View inheritance 允许在别处修改views声明(添加或者删除内容)
一般view的声明
view被声明为model
ir.ui.view
的一条记录。view的类型由跟元素arch字段来说明。<record model="ir.ui.view" id="view_id"> <field name="name">view.name</field> <field name="model">object_name</field> <field name="priority" eval="16"/> <field name="arch" type="xml"> <!-- view content: <form>, <tree>, <graph>, ... --> </field> </record>注意:view的内容是XML,arch字段必须声明为type="xml"才语法correct。
树形views
tree views也叫list views,将记录展示在表格中。
他们的root元素是<tree>。最简单的tree view在表格中展示了table中的所有字段(每个字段作为一列)。
<tree string="Idea list"> <field name="name"/> <field name="inventor_id"/> </tree>
表单views
forms通常创建用来编辑单一的记录。
他们的root元素是<form>,他们有更高级的元素(groups,notebooks)和交互元素(按钮和fields)组成。
搜索views
search views定制了search fields并与list view(和其他聚集的views)相关联。他们的root元素是<search>并且他们由能够被搜索的field组成。
如果model没有search view,Odoo会生成一个只允许通过名称查询的search view。<search> <field name="name"/> <field name="inventor_id"/> </search>
models之间的联系
一个model的记录可能关联另一个model的一条记录。例如,一个销售订单的记录将会关联一个含有客户端数据的客户端记录,同时也关联了他的online销售订单。
相关fields
相关的fields link records,相同model之间(不同等级)或者不同model间。
relational field类型为:
Many2one(other_model, ondelete='set null') 多对一
print foo.other_id.nameOne2many(other_model, related_field) 一对多
一种抽象的关系,是多对一的反转。一对多是多条记录的集合,通过set(可能为空)来访问他的结果results。
for other in foo.other_ids: print other.name注意:因为一对多是一种抽象的关系,在other_model中必须有有一个Many2one的field,且他的名称一定要是related_field
。一种多重双向的关系,任何一边的记录都能关联任意数量的另一边的记录。作为记录的集合,通过set(可能为空)来访问他的结果results。
继承
model的继承
odoo提供了两种继承机制来以模块化的方式扩展现有的model。
第一种继承机制允许一个模块能够修改另一个模块的行为。
- 向model添加一个field
- 重写model中field的定义
- 向model添加constraints,yue束。
- 向model添加方法
- 重写model中现有的方法
第二种继承机制(授权,委托,delegation)允许链接model的每一条记录到父model的记录,且提供了更明显的方式访问父记录的fields.
view的继承
为了替换修改已有的一定位置的view(通过重写他们),Odoo提供了view继承,子view的扩展被应用在root views的top,且能够添加或remove他们父view的内容。一个扩展view通过
inherit_id
field来指向他的父view,为了替换单个view,他的arch field由一系列的xpath元素来选择和更改他们父view的内容:<!-- improved idea categories list --> <record id="idea_category_list2" model="ir.ui.view"> <field name="name">id.category.list2</field> <field name="model">idea.category</field> <field name="inherit_id" ref="id_category_list"/> <field name="arch" type="xml"> <!-- find field description and add the field idea_ids after it --> <xpath expr="//field[@name='description']" position="after"> <field name="idea_ids" string="Number of ideas"/> </xpath> </field> </record>
expr
一个XPath表达式选择单个父view中的元素,如果没有元素匹配或者有多个元素,则报错。
position
匹配元素的操作
inside
在匹配元素的最后添加xpath‘s body
replace
通过xpath’s body来替换所匹配的元素
before
作为一个sibling在所匹配的元素前插入xpath‘s body
after
作为一个sibling在所匹配的元素后插入xpath‘s body
attributes
用xpath'body里特殊的attributes元素修改所匹配元素的attributes