参考文档 看云文档参考 思否ruter文档参考css
python
postgresql
node.js
less (css是静态, less是动态)
githtml
1 安装路径: /xx/xx
2 /xx/xx/odoo-bin -c odoo-dev/odoo.conf & # odoo-dev/odoo.conf 配置文件
-c 指定配置文件文件
& 后台运行node
数据库管理: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/loginpython
业务对象
Python类,这些类会被Odoo框架自动持久化,持久化的方式决定于类的定义。
数据文件
包括视图、菜单、动做、工做流、权限、演示数据等,以XML或CSV文件定义。
Web控制器
处理Web浏览器的请求
静态页面数据
网站或界面使用的图片、CSS或JavaScript文件
模块结构
每一个模块都是模块目录中的一个子目录, 能够经过 --addons-path 选项指定模块目录的路径
git
odoo的设计模式 --> MVC模式
M Model
V View
C Controllerweb
1 在odoo源码同层目录下建立目录: mkdir myaddons
2 用odoo-bin的脚手架功能建立空的odoo模块
./odoo-bin scaffold todo myaddonssql
参考:参考手册数据库
本身的笔记跳转: odoo10 orm操做segmentfault
本身的笔记跳转: odoo10视图设计模式
经过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时记录不可见
为客户端接口提供了一种方法, 只要用户填写了字段中的值, 就能够实时更新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", } }
在记录集上调用这个方法。装饰器参数指定了约束涉及的字段,当涉及的字段中任一发生改变时触发方法执行。若是不知足约束条件,该方法将引起异常:
示例
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_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"), ]
工做流是与动态业务对象相关联的模型。工做流也用于跟踪动态(随时间)演进的进程。
下面是工做流的两种实现方式
button标签的type='object'
给模型添加一个字段state, 用于定义一个工做流程
按钮 --> 模型的方法
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 获取当前对象的模型的上下文
注意: 向导记录不是永久性的, 会在一段时间后自动从数据库中删除. 这就是为何他们被称为"瞬态"
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 的公司
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动做
---> 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 表示视图类型
---> 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') 抛出警告信息
---> ir.actions.act_url
target:有两个可选值,分别是新窗口(new)打开连接,至关于 <a target='_blank' />,以及当前窗口(self)打开,至关于 <a target='_self' /> url:要打开的目标页面的连接,能够是外部页面也能够是同域下的内部页面
触发一个彻底右客户端(浏览器)执行的动做
无
参考 思否文档参考
1 基于组对表的访问权限 --> CSV文件
2 基于组对表中数据行的访问权限 --> XML文件
3 字段级别 // contraint # 经过contraint能够作到字段级别
模块分类: ir.module.category
用户组: res.groups
两个系统自带的用户组:
base.group_user 基础用户组
base.user_root 管理员帐号
用户组里每一个字段所表明的含义:
category_id:该用户组所属的模块分类 # <field name="category_id" ref="todo.module_category_todo"/> implied_ids:在当前用户组下的用户,同时加入该(字段所指定的)用户组中 users:该字段所指定的用户默认被加入到当前用户组中 # 将会默认得到此组权限的用户
(先根据上一步建立用户组)
用户组的权限定义以.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
(俗名: 规则)
模型: ir.rule
model_id:要应用该规则的模型的外部 ID # 模型的外部标识ID --> model_**_** domain_force:过滤条件,符合该条件的记录都将按照所定义权限进行检查,其中变量 user 表示当前用户的实例对象,能够直接使用 groups:应用该规则的用户组,若是不指定则默认对所有用户应用该规则
只须要在对应的菜单项上添加一个groups属性便可, 里面的值能够是逗号分隔的多个用户组的外部ID