-
Module structure
一个模块可以包含以下模块:
- 业务对象:由继承了osv.Model类的Python类申明,这些资源的持久化完全由OpenERP的ORM管理
- Data:包含元数据的XML/CSV的文件(视图和工作流定义),配置数据(模块参数化),和展示数据(可选但推荐测试)
- 报表:RML(XML格式)。HTML/MAKO或者办公软件报表模板,能与任何种类业务数据合并,并创建HTML,ODT,或者PDF报表。
模块组合:
每个模块的目录要不是在server/bin/addons目录下,要不在abbons下的另一个目录下,其都在服务器实例化时配置。为创建一个新的模块,作为例子演示OpenAcademy,可按照如下步骤:
- 在source/addons目录下创建openacademy子目录
- 创建模块的导入文件__init__.py
- 创建模块的manifield文件__openerp__.py
- 创建包含对象的Python文件
- 创建包含模块数据的xml文件,比如视图,菜单条目或者展示数据
- 可选地创建报表或者工作流
Python import file __init__.py(Python的导入文件__init__.py)
这个文件是Python'的导入文件,因为一个OpenERP模块也是一个普通的Python模块。这个文件应该导入所有其他的python文件或者子模块。
例如,如果一个模块包含了一个单一python文件openacademy.py,文件应该像这样:
import openacademy
Manifest file __openerp__.py
在创建的模块目录中,你必须添加一个__openerp__.py 文件。这个文件,必须是一个Python的字典文字,负责:
- 在服务器初始化期间决定将要解析的XML文件
- 决定创建模块的依赖
- 声明更多的元数据
这个文件必须包含有如下值的Python字典:
- name 模块的英文名
- version 模块版本
- summary 简要的描述或者关键字
- category 模块种类
- author 模块的作者
- website 模块的地址或者url
- license 模块的授权
- depends 这个模块依赖的模块列表
- data 模块安装或者更新时要加载的XML列表
- demo 模块安装或者更新并且展示标示是活跃时需加载的更多的xml文件列表
- installable True或者False。决定此模块是否安装
- auto_install True或False(默认:False)。如果设置为True,这个模块式可连接的。它将与其依赖尽快安装。
对于openacademy模块,下面是__openerp__.py文件的例子:
{
'name' : "OpenAcademy",
'version' : "1.0",
'author' : "OpenERP SA",
'category' : "Tools",
'depends' : ['mail'],
'data' : [
'openacademy_view.xml',
'openacademy_data.xml',
'report/module_report.xml',
'wizard/module_wizard.xml',
],
'demo' : [
'openacademy_demo.xml'
],
'installable': True,
}
Objects (对象)
所有的OpenERP资源都是对象:invoices(发票),partners(合作者)。元数据也是对象:menus(菜单),actions(动作),reports(报表)。。。对象名是分层的:如下所示:
- account.transfer:转账
- account.invoice:发票
- account.invoice.line:发票行
一般地,模块名是其第一个单词:account,stock,sale
那些对象作为osv.Model的子类在Python中声明。
OpenERP的ORM构建于PostgreSQL之上。之后,可能通过OpenERP使用ORM的对象接口或者直接使用SQL语句查询对象。
但是直接在PostgreSQL中读写是很危险的,因为你将漏掉重要的步骤,像约束检查或者工作流修正。
XML Files(XML文件)
模块目录中的XML文件用于当模块安装或者更新时,初始化或者更新数据库。它们用于许多地方,这里举了一些例子
- 初始化和演示数据声明
- 视图声明
- 报表声明
- 工作流声明
OpenERP XML文件的一般结构的更多详情请参考XML Data Serialization部分。这里你将了解到initialization 和demonstration data declarationXML文件。下面部分只是涉及到XML特定的部分,如actions, menu entries, reports, wizards 和workflows声明。
<?xml version="1.0"?>
<openerp>
<data>
<record model="model.name_1" id="id_name_1">
<field name="field1"> "field1 content" </field>
<field name="field2"> "field2 content" </field>
(...)
</record>
<record model="model.name_2" id="id_name_2">
(...)
</record>
(...)
</data>
</openerp>
<record>¶
在指定的OpenERP模型中定义了一个新的记录
@model(必须)
要被创建/插入的模型名
@id(必须)
external ID(外部ID),也允许这个文件的其他部分或者另外一个文件的关联这个记录(通过field/@ref 或者ref() 函数)
一个record标签一般包含多个field标签,用来创建时指定record字段的值 。除非需要,剩余的字段设置为默认值。
<field>¶
在其大多数基本用法中,field标签将设置其主体(一个字符串)作为record 的@name的值。
其他属性要不预处理其主体或者完全替代其用法。
@name(必选)
record模型的字段名
@type(可选)
char,int,float, list,tuple,xml 或者 html,file 或者base64之一。将field的主体转换为指定的类型(或者校验主体的内容)
- xml 将在单一<data>根下添加多个XML节点
- 在xml和html中,多个id可以使用%(id_name)s
- list 和tuple的元素使用<value>的子节点指定,如同<field>同样的属性
- file是模块的本地路径并使用当前模块名字保存路径前缀,用逗号隔开。使用get_module_resource().
- base64 希望是字节数据,编码为base64并设置。与@file同时用。
@file
能够使用char和base64类型,从指定的文件获取字段内容,而不是通过字段的文本。
@model
模型用于@search搜索,或者用于@eval放入内容的注册对象。@search是必选的而@eval是可选的。
@eval(可选)
一个Python表达式,通过计算获取record上设置的值。
@ref(可选)
通过 external id 连接其他的记录。在同一个模块中定义的记录,模块前缀可能省略
@search(可选)
在@model中调查领域(Python计算表达式)来获取字段上设置的记录
为m2m字段设置所有的匹配,第一个id用于其他字段类型
Example
<record model="ir.actions.report.xml" id="l0">
<field name="model">account.invoice</field>
<field name="name">Invoices List</field>
<field name="report_name">account.invoice.list</field>
<field name="report_xsl">account/report/invoice.xsl</field>
<field name="report_xml">account/report/invoice.xml</field>
</record>
让我们看看OpenERP源码中的例子(base模块中的base_demo.xml )
<record model="res.company" id="main_company">
<field name="name">Tiny sprl</field>
<field name="partner_id" ref="main_partner"/>
<field name="currency_id" ref="EUR"/>
</record>
<record model="res.users" id="user_admin">
<field name="login">admin</field>
<field name="password">admin</field>
<field name="name">Administrator</field>
<field name="signature">Administrator</field>
<field name="action_id" ref="action_menu_admin"/>
<field name="menu_id" ref="action_menu_admin"/>
<field name="address_id" ref="main_address"/>
<field name="groups_id" eval="[(6,0,[group_admin])]"/>
<field name="company_id" ref="main_company"/>
</record>
这最后 一个record定义了admin用户
- login,password字段等一目了然
- ref 属性允许关联两个记录
<field name="company_id"ref="main_company"/>
字段company_id是用户对象与company对象多对一的关系,并且main_company是外键id。
- eval属性允许在xml中加入一些Python代码:这里group_id字段是多对多关系。对于这样的字段, "[(6,0,[group_admin])]" 表示:移除与当前用户关联的组并且使用列表[group_admin]作为最新的关联的组(并且group_admin是另一个记录的id)
- search属性允许你在不知其xml id 时,查找关联的记录。你可以指定一个查询条件来查找所要的记录。条件是一列相同格式的元组而不是预定义的查询方法。如果有多个方法,随机选择一个(第一个)
<field name="partner_id" search="[]" model="res.partner"/>
下面是一个在demo数据使用查询的典型例子。这里我们不关心使用哪个合作者来测试,所以我先给一个空的列表。注意model属性是必选的。
Function tag(功能标记)
一个功能标记可以持有其他的功能标记
model:必选
使用的模式
name:必选
功能名
eval
应该估算要调用方法的列表参数,除了cr和uid
Example
<function model="ir.ui.menu" name="search" eval="[[('name','=','Operations')]]"/>
Views(视图)
视图是一种在客户端显示对象的方式。它们指明了如何在屏幕上分布来自对象的数据。
有两种类型的视图:
- 表单视图
- 树形视图
列表是一个简单的树形视图。
同一对象可能有多种视图:这类第一次定义的视图(树形,表单。。。)将被默认用作这类的默认视图。这样你可能有一个默认的树形视图(一个多对一关系的视图)和将有要显示的或多或少信息的指定视图(这是要双击目录条目)。例如,由于产品版本不同,其将有多个视图
视图定义在XML文件中
如果没有给对象定义一个视图,对象将自动创建一个显示其的视图。这个虽然能限制开发者的工作但是将创建不亚于开发者的视图。
Usage Example (使用例子)
当打开发票时,客户端按照以下操作链进行:
- 一个Action请求打开发票(给了对象的数据(account.invoice),视图,领域(例如,未付款的发票))
- 客户端向服务器请求(使用XML-RPC)为发票对象定义的视图和必须显示的数据
- 客户端通过视图显示表单
To develop new objects(开发新的对象)
新对象的设计由最小量限制:创建对象并且可选的创建显示他们的视图。PostgreSQL表没有必要手动创建,因为对象可以自动创建它们(或者表已经存在了)
Reports(报表)
OpenERP使用灵活并功能强大的报表系统。可以创建PDF或者HTML格式的报表。报表设计在数据层和演示层之间、
详情请参考报表部分。
Workflow(工作流)
对象和 视图允许简单地定义新的表单,列表/树形和之间的交互。但是这些还不够,你必须动态定义这些对象。
一些例子:
- 一个确认销售订单必须通过几个条件创建发票
- 已支付发票,必须在某些情况下,启动shipping order
工作流描述了图片的交互。一个或者多个工作流可能关联到这些对象。工作流不是必须的;一些对象没有工作流。
下面的例子用于销售订单。必须依据特定条件创建发票和shipping 订单。
在这章图中,节点表示要处理的actions
- 创建一张发票
- 取消销售订单
- 创建航运订单,。。。
箭头是条件:
- 等待订单校验
- 支付发票
- 点击取消按钮
方格节点表示其他工作流
- 发票
- 航运
i18n(国际化)
在5.0版本已经变化
每个模块有其自己的i18n目录。另外,OpenERP现在可以处理.po[1] 文件作为导入/到处格式。翻译的文件在模块安装或更新的时候自动加载。
翻译由 Launchpad Web interface处理。这里你将找到翻译项目的列表