odoo10基础

参考文档 看云文档参考    思否ruter文档参考

odoo开发,需要那些工具

python
postgresql
node.js
less (css是静态, less是动态)
git

运行odoo

1 安装路径: /xx/xx
2 /xx/xx/odoo-bin -c odoo-dev/odoo.conf & # odoo-dev/odoo.conf 配置文件
  -c 指定配置文件文件
  & 后台运行

odoo技巧

数据库管理:http://127.0.0.1:8069/web/database/manager
数据库选择:http://127.0.0.1:8069/web/database/selector
数据库指定:?db=database

后台
  http://127.0.0.1:8069/web/
前台
  http://127.0.0.1:8069/
登录
  http://127.0.0.1:8069/web/login

Odoo模块组成

业务对象
  Python类,这些类会被Odoo框架自动持久化,持久化的方式决定于类的定义。
数据文件
  包括视图、菜单、动作、工作流、权限、演示数据等,以XML或CSV文件定义。
Web控制器
  处理Web浏览器的请求
静态页面数据
  网站或界面使用的图片、CSS或JavaScript文件
模块结构
  每个模块都是模块目录中的一个子目录, 可以通过 --addons-path 选项指定模块目录的路径

odoo的设计模式 --> MVC模式
  M Model
  V View
  C Controller

创建模块

1 在odoo源码同层目录下创建目录: mkdir myaddons
2 用odoo-bin的脚手架功能创建空的odoo模块
./odoo-bin scaffold todo myaddons

odoo orm

参考:参考手册

自己的笔记跳转:  odoo10 orm操作

视图

自己的笔记跳转:  odoo10视图

domains

通过domain来过滤数据记录
domain作用子一个model上: 用model.search(domain)
Domain是定义模型子集的规则集合。domain表达式是由多个(field_name, operator, value)元组构成的列表或数组

field_name -- 字段名或者用.号分隔的Many2one关系的字段如:'street' , 'partner_id.country'
operator(str) -- 用于对字段值和给定值进行比较的运算符:
    =,!=,>,>=,<,<=,
    =?(值为false或none时返回true,否则与=效果一致)
    =like()将字段数据与value进行匹配,_代表匹配单个字符、%匹配0或多个字符
    like() 将字段数据与%value% 进行匹配,
    not like 不与%value%匹配
    ilike 忽略大小写的like函数
    not ilike 忽略大小写的not like
    =ilike 忽略大小写的=like
    in 与value的任意值相等,value须为值列表
    not in 与value的任意值都不相等
    child_of 是否由value派生而来
value 对应值,必须与相应条件对应
    多个domain表达式可用运算符进行连接,运算符写在两个表达式之前。
        & 逻辑与 ,| 逻辑或,!逻辑非

 

1 作用在关联字段上
  示例: 当为授课选择讲师时,只有instructor值为True的讲师会被显示出来。
  instructor_id = fields.Many2one('res.partner', string="Instructor", domain=[('instructor', '=', True)])

  注意: 声明为文字列表的domain会在服务端进行计算,右侧不可以是动态的字段; 而声明为字符串的domain是在客户端进行计算的,右侧可以是动态的字段

2 作用在客户端上
  当在客户端界面选择记录集时,domain参数可以添加到关联字段上,以限制只显示有效的关联字段。
  <field name="instructor_id" domain="[('instructor', '=', True)]"/>

计算字段

odoo中提供一种每次引用字段, 通过方法动态计算的方式来获取字段值的方法

1 创建计算字段
  - 创建一个字段
  - 将其属性compute设置为(计算)方法名称

2 计算方法
  # ORM使用depends()装饰器来指定计算方法的依赖性。当某些依赖关系被修改后,ORM层通过给定的依赖关系来触发字段的重新计算。

  @api.multi
  @api.depends('value')
  def _compute_name(self):
    for record in self:
      record.name = "Record with value %s" % record.value

默认值

字段加上属性 default

  - 可以是一个值
  - 有返回值的匿名函数

对象self.env提供对请求参数和其他有用的东西的访问

self.env.cr 或者 self._cr            是数据库游标对象,通常用于查询数据库
self.env.uid或者self._uid            是当前用户的数据库ID
self.env.user                        是当前用户记录
self.env.ref(xml_id)                返回XML ID对应的记录
self.env[model_name]                返回给定模型的实例

Odoo 有内置规则:active字段值为False时记录不可见

onchange

为客户端接口提供了一种方法, 只要用户填写了字段中的值, 就可以实时更新form表单, 而无需向数据库保存任何内容

示例

@api.onchange('amount', 'unit_price')        # onchange()的参数指定了在那个字段改变时,触发方法
def _onchange_price(self):
    # 业务逻辑
    if flag:
        return {    # 可以返回一个错误信息
            'warning': {
                'title': "Something bad happened",
                'message': "It was very bad indeed",
            }
        }

模型约束

python代码级别约束

在记录集上调用这个方法。装饰器参数指定了约束涉及的字段,当涉及的字段中任一发生改变时触发方法执行。如果不满足约束条件,该方法将引发异常:

示例

from odoo.exceptions import ValidationError

@api.constrains('age')
def _check_something(self):
    for record in self:
        if record.age > 20:
            raise ValidationError("Your record is too old: %s" % record.age)
    # all records passed the test, don't return anything

sql数据库级别约束

SQL约束通过模型属性_sql_constraints进行定义。

它是一个三元素的元组的列表(name, sql_definition, message)

  - name 是SQL约束名称,
  - sql_definition 是约束规则,
  - message 是违反约束规则时的警告信息。

示例

_sql_constraints = [
    ('name_description_check',
     'CHECK(name != description)',
     "The title of the course should not be the description"),

    ('name_unique',
     'UNIQUE(name)',
     "The course title must be unique"),
]

工作流

工作流是与动态业务对象相关联的模型。工作流也用于跟踪动态(随时间)演进的进程。

下面是工作流的两种实现方式

1 伪工作流

button标签的type='object'

给模型添加一个字段state, 用于定义一个工作流程

按钮 --> 模型的方法

2 真工作流

button标签的type='workflow'

与模型相关的工作流仅在创建模型记录时被创建。因此,在工作流定义之前创建的授课实例是没有与之对应的工作流实例的。

工作流的构成

工作流

# 有点类似一个【model的工作流模板】, 之后此model的工作流实例根据这个模板生成

xml示例代码:

<record model="workflow" id="wkf_session">
    <field name="name">OpenAcademy sessions workflow</field>
    <field name="osv">openacademy.session</field>
    <field name="on_create">True</field>
</record>

活动(节点)

# 活动定义了应在Odoo服务器内完成的工作          例如更改某些记录的状态或发送电子邮件。

不同的调用方式:

<field name="kind">function</field>        # python代码     
<field name="kind">dummy</field>           # 服务器的code
                                           # 还有 Subflow 和 Stop all,可以参考官方文档

xml示例代码:

<record model="workflow.activity" id="draft">
    <field name="name">Draft</field>
    <field name="wkf_id" ref="wkf_session"/>
    <field name="flow_start" eval="True"/>        # 标示了活动的开始节点
    <field name="kind">function</field>
    <field name="action">action_draft()</field>
</record>

转换

# 控制工作流如何从活动到活动。

xml示例代码:

<record model="workflow.transition" id="session_draft_to_confirmed">
    <field name="act_from" ref="draft"/>
    <field name="act_to" ref="confirmed"/>
    <field name="signal">confirm</field>        # 【信号】: 通过button触发, button会根据name去找到相应的signal
</record>

实例

# 创建一个recoed时, 会根据工作流模板, 生成工作流实例

有点类似python面向对象的实例化

条件

当条件被满足时, 自动状态迁移, 有点类似 (条件+onchange)

自动化的工作流: 设置一个condition

xml示例代码:

<record model="workflow.transition" id="session_auto_confirm_half_filled">
    <field name="act_from" ref="draft"/>
    <field name="act_to" ref="confirmed"/>
    <field name="condition">taken_seats > 50</field>
</record>

向导

model --> ir.actions.act_window

在odoo中通过使用向导创建一个表单与用户进行交互, 向导的model使用TransientModel定义

运行wizard: 可以通过ir.actions.act_window模型表里的记录启动, 可以从menu里或者某个button触发;

      另外一种方式, 在form view上方的下拉按钮组(context action)中调用, 设置好src_model关联对应的model

1 向导视图中:

src_model     指向上下文的模型
res_model     指向向导的模型

target="new"        将弹出一个新窗口打开向导
special="calcel"    关闭向导窗口而不保存

2 向导模型中

self._context        获取当前对象的模型的上下文

注意: 向导记录不是永久性的, 会在一段时间后自动从数据库中删除. 这就是为什么他们被称为"瞬态"

odoo报表

报表构成

1 在ir.actions.report.xml中定义报表记录, 使用<report>设置报表的各种基本参数

id                 外部标示
name            助记符/描述符
model            报告涉及的模型
report_type        qweb-pdf/qweb-html
report_name        打印出来的名字
groups            允许哪些组可以查看/使用报表
attachment_use    设成True, 报表将使用附件表达式生成的名称存为记录的附件
attachment        表达式
paperformat        纸质格式的外部ID, 默认为公司的纸质格式

2 Qweb view定义报表样式

docs是从context发送过来的变量(上下文), 代表报表内容记录, 
user代表打印此报表的人

- external_layout        将在报表上添加默认页眉和页脚
- PDF的body将会包含在<div class="page"> 
- <template>的id必须是<report>里指定的name
- <template>里可以使用的变量
    docs             记录当前报表
    doc_ids         docs 记录的id列表
    doc_model         模型为 docs 记录
    time             引用Python标准库的 time
    user             res.user 记录用户打印报表
    res_company     记录当前 user 的公司

Qweb常用指令

1 数据输出

t-esc = 'value'            会做html转义, 有xss攻击的危险
t-raw                      不转义

2 条件

t-if
t-elif
t-else

3 循环

t-foreach t-as
t-esc # 设置: t-set = '...' t-value = ''

4 属性

计算属性: t-attr
有3中不同的形式:

1 t-attr-$name
2 t-attf-$name
3 t-att-mapping
  t-att-pair

5 设置变量

通过set指令完成

两种方式

1 t-value = '2+1'        # 可以是表达式
2 如果没有t-value, 则节点的body将设置为变量的值

6 调用子模版

使用t-call调用其他模版

神奇的0变量

主模版:
    <div>
        This template was called with content:
        <t t-raw="0"/>        # 将会渲染为子的内容, 相当于为子的body预留位置
    </div>

调用子模版:
    <t t-call="other-template">
        <em>content</em>
    </t>
    
将会渲染成:
    <div>
        This template was called with content:
        <em>content</em>
    </div>

动作

参考 odoo10动作

1 窗口动作

--->  ir.actions.act_window

res_model:要打开的视图(窗口)关联的数据模型
view_type:视图类型,默认值为 form,一般情况下我们取默认值就可以了
view_mode:允许打开的视图类型,以逗号分隔,默认值为 tree,form
target:打开的窗口类型,常用的有 current(当前窗口打开)和 new (弹窗打开)这两种,默认为 current

还有一些非必填的字段在某些时候我们是会用上的,这里也分列出来:
view_ids:关联的视图对象 id,需注意区分和 view_id 的区别
view_id:关联的视图的 id, 例如在不同时候需要打开同一个数据模型不同的表单视图,就可以通过这个字段指定要打开的视图的 id
res_id:仅在视图类型为 form 时有效,表示打开该 id 对应的记录的表单视图,如未指定则打开新建页面
context:传递到上下文中的数据,一个字典
domain:过滤规则,对视图中的记录进行过滤
limit:列表中每页显示的记录数量,默认为 80
search_view_id:指定搜索视图,不指定则按默认规则加载
multi:如果设置为 True 且动作绑定了模型(src_model)的话,该动作按钮会只出现在所绑定模型列表视图的「动作」下拉列表中(在搜索视图左侧)
views:由 (view_id, view_type) 这样的元组对组成的列表,view_id 为指定视图的 id 或是 False(按默认值取出对应视图),view_type 表示视图类型

2 服务器动作

--->  ir.actions.server

model_id:当前的动作是在哪个模型上运行的
binding_model_id:绑定的模型,当前动作将会出现在绑定的模型的视图中
state:服务器动作的类型,总共有 4 种可选的类型,分别是 code(执行 Python 代码),object_create(创建一条新记录),object_write(更新记录),multi(执行多个动作)
code:对应 state 的类型 code,为当前动作运行时所要执行的 Python 代码

我们定义的所有模型都会在 ir.model.data 对应的表中存在相应的记录

接下来我们再看到字段 code 里面的内容,在这里面我们有一些变量是可以直接使用的:
env:Odoo 的运行环境
model:动作触发时对应的 Odoo 模型实例
record:动作触发时对应的单个记录(如在表单视图中运行对应当前表单所指向的记录),可能是空的
records:动作触发时对应的记录集(如在列表视图中勾选多条记录触发,记录集指向这些选中的记录),可能是空的
Python 库:time, datetime, dateutil, timezone 时间相关的 Python 库
log:用来记录日志信息
Warning:通过 raise Warning('xxxxx') 抛出警告信息

3 URL动作

--->  ir.actions.act_url

target:有两个可选值,分别是新窗口(new)打开链接,相当于 <a target='_blank' />,以及当前窗口(self)打开,相当于 <a target='_self' />
url:要打开的目标页面的链接,可以是外部页面也可以是同域下的内部页面

4 客户端动作

触发一个完全右客户端(浏览器)执行的动作

5 报表动作

安全与权限

参考 思否文档参考

1 基于组对表的访问权限 --> CSV文件
2 基于组对表中数据行的访问权限 --> XML文件
3 字段级别     // contraint     # 通过contraint可以做到字段级别

1 用户组的权限

模块分类: ir.module.category
用户组: res.groups

a 定义用户组

两个系统自带的用户组:

base.group_user    基础用户组
base.user_root    管理员账号

用户组里每个字段所代表的含义:

category_id:该用户组所属的模块分类    # <field name="category_id" ref="todo.module_category_todo"/>
implied_ids:在当前用户组下的用户,同时加入该(字段所指定的)用户组中    
users:该字段所指定的用户默认被加入到当前用户组中    # 将会默认获得此组权限的用户

b 用户组的权限

(先根据上一步创建用户组)

用户组的权限定义以.csv文件存储的
默认的权限记录文件: security/ir.model.access.csv
里面有8个字段, 分别代表的含义如下;

id:这条权限记录的 id,可以类比为 xml_id    # 类似xml的外部标识
name:权限记录的名称
model_id:id:要配置权限的模型的外部 ID (以 model_ 开头)
group_id:id:应用此条权限配置的用户组的 id,若为空则默认对所有用户组生效        # 上一步创的用户组id
perm_read:读取记录的权限,1 为拥有该权限,0 为不分配该权限
perm_write:编辑更新记录的权限,取值同上
perm_create:创建新记录的权限,取值同上
perm_unlink:删除记录的权限,取值同上

示例

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_app02_contract,app02.contract,model_app02_contract,,1,1,1,0

2 记录集权限

(俗名: 规则)

模型: ir.rule

model_id:要应用该规则的模型的外部 ID # 模型的外部标识ID --> model_**_**
domain_force:过滤条件,符合该条件的记录都将按照所定义权限进行检查,其中变量 user 表示当前用户的实例对象,可以直接使用
groups:应用该规则的用户组,如果不指定则默认对全部用户应用该规则

菜单隐藏

只需要在对应的菜单项上添加一个groups属性即可,  里面的值可以是逗号分隔的多个用户组的外部ID

posted @ 2019-03-18 17:43  孙昌恒  阅读(1291)  评论(0编辑  收藏  举报