-----------------
更新时间
17:44 2016-02-17 星期三
-----------------
* 模板(Templating)
<template id="..." name="...">
html
</template>
--------
<record id="..." model="ir.ui.view">
<field name="name">...</field>
...
<field name="arch" type="xml">
html
</field>
</record>
#渲染模板
http.request.render(template[,values])
@http.route('/hello/')
def hello(self, **kw):
return http.request.render(module.hello)
-------
<template id="hello">
<p> hello , <t t-esc="name"/></p>
</template>
--------
return http.request.render(module.hello,{'name':"World"}) # 带参数
# Qweb 设置变量值
<template id="hello">
<t t-set="greet" t-value="name+'!!!'">
<p> hello , <t t-esc="greet"/></p>
</template>
--------
<template id="hello">
<t t-set="greet" t-valuef="{{name}}!!!">
<p> hello , <t t-esc="greet"/></p>
</template>
---------
原样输出
<template id="hello">
<t t-set="greet">
<em>Hello</em>, <t t-esc="name"/>
</t>
<p> hello , <t t-raw="greet"/></p>
</template>
# Qweb 语句
条件语句
<template id="hello">
<p>
<span t-if="name=='World'" />
Hello World!
</span>
</p>
</template>
-----
<template id="hello">
<t t-set="condition" t-value="name=='World'">
<p>
<span t-if="condition" />
Hello World!
</span>
</p>
<p>
<span t-if=" not condition" />
Hello not World!
</span>
</p>
</template>
循环语句
<template id="hello">
<ul>
<li t-foreach="name" t-as="letter">
<t t-esc="letter_index"/>:<t t-esc="letter" />
</li>
</ul>
<template>
-------
<t t-foreach="seq" t-as="value">
* value 项值
* value_size 大小
* value_all 总数
* value_index 索引号
* value_first:bool 第一个
* value_last:bool 最后一个
* value_parity:'even'|'odd' 当前是第奇数还是偶数
调用其它模板
采用t-call
<template id="sub">
<t t-esc="identifier" />
</template>
<template id="hello">
<p>
hello,
<t t-call="module.sub">
<t t-set="identifier" t-value="name" />
</t>
</p>
</template>
属于设置
t-att-{attname}="{expression}"
t-attf-{attname}="{expression}"
------
<template id="hello">
<p t-att-class="name.lower()">Hello,world</p>
<p t-attf-class="cl-{{name.lower()}}">Hello,world</p>
<template>
字段渲染
@http.route('hello/<model("res.users"):user') # 给用户的id即可
def hello(self,user,**kw)
return http.request.render('module.hello',{'user':user})
-------
<template id="hello">
<p t-field="user.display_name" />
</template>
---------
可用字段选择修饰
<template id="hello">
<p t-field="user.creat_date" />
<p t-field="user.creat_date" t-filed-options='{"format":"long"}'/>
<p t-field="user.creat_date" t-filed-options='{"format":"EEE"}'/>
</template>
-------------
<template id="hello">
<p t-field="user.wealth" />
<p t-field="user.wealth" t-filed-options='{
"widget":"monetary"
"display_currency":"user.company_id.currency_id"
}'/>
</template>
------------
<template id="hello">
<p t-field="user.create_date" t-field-options='{"widget":relative}}' />
</template>
模板继承
<template id="hello">
<p> Base template </p>
</template>
<template id="hello2" inherit_id="hello" name="Extender">
<xpath expr="//p" position="before">
<h1>Extended!</h1>
</xpath>
</template>
得到的结果:
<h1>Extended!</h1>
<p>Base template</p>
--------------
<template id="hello">
<p class="a">A</p>
<p class="b">B</p>
</template>
<template id="hello2" inherit_id="hello" name="Extender">
<xpath expr="//p[hasclass('b')]" position="before">
<h1>Extended!</h1>
</xpath>
</template>
得到的结果:
<p class="a">A</p>
<h1>Extended!</h1>
<p class="b">B</p>
----------
调用系统的基础模板:
<template id="hello">
<t t-call="website.layout">
<p class="a">A</p>
<p class="b">B</p>
</t>
</template>
<template id="hello2" inherit_id="hello" name="Extender">
<xpath expr="//p[hasclass('b')]" position="before">
<h1>Extended!</h1>
</xpath>
</template>
* 窗口操作
如下一些代码
<?xml version="1.0" encoding="utf-8" ?>
<openerp>
<data>
<act_window id="action_todo_stage"
name="To-Do Task Stages"
res_model="todo.task.stage"
view_mode="tree,form" />
<act_window id="todo_app.action_todo_task"
name="To-Do Task "
res_model="todo.task"
view_mode="tree,form,calendar,gantt,graph"
target="current"
context="{'default_user_id':uid}"
domain="[]"
limit="80" />
<act_window id="action_todo_task_stage"
name="To-Do Task Stages"
res_model="todo.task.stage"
src_model="todo.task"
multi="False" />
</data>
</openerp>
可以用ir.action.act_window 重新其中一菜单对角
<record id="action_todo_stage" model="ir.actions.act_window">
<field name="name">To-Do Task Stage</field>
<field name="res_model">todo.task.stage</field>
<field name="view_mode">tree,form</field>
</record>
窗口的动作是存在 ir.actions.act_window 模型中的,我们可以在xml文件中用<act_window>来快捷定义
# name 显示的标题
# res_model 动作响应的目标模型
# view_mode 列出动作响应对应可用的视图类型
# target 如果设置为new 就打开新窗口,默认是 current
# context 设置目标视图的上下文
# domain 过滤记录按条件
# limit 指列表视图时,一页的记录数,默认是80
# src_model 指定可以启动视图的更多按钮
# multi 设为True, 更多按钮显示在列表视图,否则显示在表单视图
* 菜单项
如下一些代码
<menuitem id="menu_todo_task_main"
name="To-Do" parent="mail.mail_my_stuff"/>
<menuitem id="todo_app.menu_todo_task"
name="To-Do Tasks"
parent="menu_todo_task_main"
sequence="10"
action="todo_app.action_todo_task"/>
<menuitem id="menu_todo_task_stage"
name="To-Do Stages"
parent="menu_todo_task_main"
sequence="20"
action="action_todo_stage"/>
在 设置-> 技术-> 用户界面-> 菜单 可以看到已定义的菜单
菜单是存在 ir.ui.menu 模型中的,我们可以在xml文件中用<menuitem>来快捷定义
# name 在视图中显示的名字
# sequence 显示排序
# parent 本菜单的父菜单,子菜单都要指定,只有顶级菜单不要指定
# action 本菜单的连接动作
* 上下文(Context)
# 上下文 是一个字典类型的数据,用于客户端和服务端的处理,
可用于视图间信息传递,
例子:{'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 1}
{'default_user_id': uid} 用当前用户作为默认用户
{'search_default_filter_my_tasks': True}
* Domain 表达式
# 用于过滤记录数,相当于sql的where
('field', 'operator',value) 每个条件表达式是元组类型
domain=[('user_id', '=', uid)] 当前用户做为条件过滤
#操作符如下:
<,>,<=,>=,!=
=like
like, ilike(大小写不敏感)
child_of 找直接和间接的子对象
in, not in
#条件可以用逻辑符连起来 用列表类型来组织
& 是且的意思,是默认
|是或
! 是非,相反的意思
['!',('user_id','=',uid)] 不是当前用户的记录
['|',('user_id','=',uid),('user_id','=',False)] 不是当前用户,或没有用户的记录
复杂一点的:
['|', ('message_follower_ids', 'in', [user.partner_id.id]),'|', ('user_id', '=', user.id),
('user_id', '=', False)]
逻辑是连后面两个domain条件
* 三个主要的视图 list或 tree视图, 表单form视图, search搜索视图 对应模型 ir.ui.view
* 表单视图
# 添加在动作和菜单项后面 <act_window> <menuitem>
代码如下:
<record id="view_form_todo_task_ui" model="ir.ui.view">
<field name="name">view_form_todo_task_ui</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<form>
<header> <!-- Buttons and status widget --> </header>
<sheet> <!-- Form content --> </sheet>
<!-- History and communication: -->
<div class="oe_chatter">
<field name="message_follower_ids"
widget="mail_followers"/>
<field name="message_ids"
widget="mail_thread"/>
</div>
</form>
</field>
</record>
#包含三个可视域:
<header>
<sheet> 放内容的
<bottom> 历史记录和社交部分
# header 状态栏
<header>
<field name="stage_state" invisible="True"/>
<button name="do_toggle_done" type="object"
attrs="{'invisible':
[('stage_state','in',['done','cancel'])]}"
string="Toggle Done" class="oe_highlight"/>
<!-- Add stage statusbar: ... -->
</header>
@ class="oe_highlight" 加高亮
@ invisible 为可见性,还可以用到其它元素上,不仅在<botton>上
* 视图元素
#按钮<button>,支持的属性
icon 可用的icon在 addons/web/static/src/img/icons
string 按钮的显示文字
type 值可以是 workflow, object action
name 就是要触发的方法标识
args 传递方法的参数
content 上下文
confirm 针对对话框的确认
special="cancel" 用于向导
#字段<field>,支付的属性
name 字段技术名
string 显示名
help 帮助提示
placeholder 占位文字
widget 小物件
options 小物件对应的选项
class 加载类名
invisible="1" 标识不可见
nolabel="1" 不显示标签,会用于<group>之内
readonly="1" 标识只读
required="1" 标识不能为空
sum,avg 小计,平均值
password="True" 密码框
filename 文件上传用
mode="tree" One2many字段
#关联字段
options={'no_open':True,'no_create':True}
常用于 context 和 domain中
# 小物件
用于文本字段
email url html
用于数字字段
float_time monetary progressbar
用于关联和选择
many2many_tags
selection
radio
kanban_state_selection
priority
* 事件变化
@api.onchange('field1','field2')
* 动态视图
# group
# states
增加灵活性 用 refers_to
<field name="refers_to"
attrs="{'invisible': [('state','=','draft')]}" />
* 列表视图
<record id="todo_app.view_tree_todo_task" model="ir.ui.view">
<field name="name">To-do Task Tree</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<tree editable="bottom"
colors="gray:is_done==True"
fonts="italic: state!='open'" delete="false">
<field name="name"/>
<field name="user_id"/>
</tree>
</field>
</record>
# <tree>
editable 设置字段在列表直接可以编辑
colors 按条件设定记录的颜色
fonts 按条件设定记录的字体
create,delete,edit 若设置为false 则为不可用
* 搜索视图
代码如下:
<record id="todo_app.view_filter_todo_task"
model="ir.ui.view">
<field name="name">To-do Task Filter</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<search>
<field name="name" domain_filter="['|',
('name','ilike',self),('user_id','ilike',self)]"/>
<field name="user_id"/>
<filter name="filter_not_done" string="Not Done"
domain="[('is_done','=',False)]"/>
<filter name="filter_done" string="Done"
domain="[('is_done','!=',False)]"/>
<separator/>
<filter name="group_user" string="By User"
context="{'group_by': 'user_id'}"/>
</search>
</field>
</record>
# <search>
上面显示,只有name 和 user_id 搜索
field元素定义的属性
name 字段标识名
string 标签名
operator 操作符
domain_filter 过滤记录按条件
groups 用于分组
filter元素支持属性
name 指定动作标识符
string 标签名
domain 过滤记录按条件
content 上下文
groups 分组列出
* 日历视图
<record id="view_calendar_todo_task" model="ir.ui.view">
<field name="name">view_calendar_todo_task</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<calendar date_start="date_deadline" color="user_id"
display="[name], Stage [stage_id]">
<!-- Fields used for the text of display attribute -->
<field name="name"/>
<field name="stage_id"/>
</calendar>
</field>
</record>
#<calendar>
date_start 开始日期
date_end 结束日期
date_delay 周期
color 用颜色的实体
display 显示文字
* 甘特视图
<record id="view_gantt_todo_task" model="ir.ui.view">
<field name="name">view_gantt_todo_task</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<gantt date_start="date_deadline"
default_group_by="user_id"/>
</field>
</record>
#<gantt>
date_start 开始日期
date_end 结束日期
date_delay 周期
progress 进度百分比
default_group_by 任务分组条件
* 图表视图
<record id="view_graph_todo_task" model="ir.ui.view">
<field name="name">view_graph_todo_task</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<graph type="pivot">
<field name="stage" type="col"/>
<field name="user_id"/>
<field name="date_deadline" interval="week"/>
<field name="effort_estimate" type="measure"/>
</graph>
</field>
</record>
#<graph>
字段支持的属性<field>
name 字段标识名
type 分组方式,默认是row 行 ,设定可以是col列
interval 时间度量 day,week,month,quarter 或 year
作者:陈伟明 | 联系 : QQ 942923305 | 微信 toby942923305 | E-mail: toby2chen@hotmail.com