(04)odoo视图操作
-----------------
更新时间
19:04 2016-09-29 星期四
11:17 2016-09-18 星期日
18:13 2016-04-05 星期二
15:05 2016-03-14 星期一
11:46 2016-02-25 星期四
14:51 2016-02-23 星期二
18:07 2016-02-19 星期五
17:44 2016-02-17 星期三
-----------------
* 视图标签类型
# <record>标签有属性 model="ir.ui.view" ,它包含本身的视图定义
# <record>标签有属性 mo="ir.actions.act_window",它将动作和视图链接起来
# <menuitem>标签,把菜单和动作链接起来
* 模板(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>
-----------
* 视图
<record id="view_id" model="ir.ui.view">
<field name="name">view.name</field>
<field name="model">object_name</field>
<field name="type">form</field>
<field name="priority" eval="16" />
<field name="arch" type="xml">
<!-- view content <form>,<tree>,<graph>,.. -->
</field>
</record>
属性:
openerp/addons/base/ir/ir_ui_view.py view类中的_columns
model:固定为 ir.ui.view
id 唯一,调用和继承会用到
name 视图名称
model 对象
type 有多种类型 tree,form,graph,calendar,diagram,gantt,kanban,search
priority 排序
* 视图继承(用于修改已有的视图):
这里有一个小技巧:
当你继承父视图,
1.只添加字段时,本视图外id值可以和父视图id值 一样,这样后面再继承方便
2.当要隐藏或删除父字段时,本视图外id不能和父视图id值一样,否则后面无法升级模块
<record model="ir.ui.view" id="view_partner_form">
<field name="name">res.partner.form.inherit</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" /> <!--声明要修改那一个视图-->
<field name="arch" type="xml">
<notebook position="inside">
<page string="Relations">
<field name="relations_ids" colspan='4' nolabel="1" />
</page>
<notebook>
<field>
</record>
所有的操作只能在
<field name="arch" type="xml">... </field>
定位5种属性
@ inside(默认):附加在标签内
@ after:后添加内容标签
@ before:前的内容标签
@ replace: 更换标签内容
@ attributes: 更改标签内容的属性
支持定位方法:
<notebook position="inside">
<xpath expr="//page[@name='page_history']" position="inside">
<field name="mobile" position="after">
<filter name="consumable" position="after" >
<group name="bank" position="after">
<xpath expr="//field[@name='standard_price']" position="replace">
<xpath expr="//button[@name='open_ui']" position="replace">
<xpath expr="//div[@class='oe_employee_details']/h4/a" position="after">
<xpath expr="//form/sheet/notebook/page/field[@name='line_ids']/tree/field[@name='analytic_account_id']"
position="replace">
<xpath expr="/form/sheet/notebook/page/field[@name='line_ids']/form/group/field[@name='analytic_account_id']"
position="replace">
# 更换内容:
<record model="ir.ui.view" id="view_partner_form1">
<field name="name">res.partner.form.inherit1</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<page string="Extra Info" position="replace">
<field name="relations_ids" colspan='4' nolabel="1" />
</page>
<field>
</record>
# 删除内容:
<record model="ir.ui.view" id="view_partner_form2">
<field name="name">res.partner.form.inherit2</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="lang" position="replace"/>
<field>
</record>
# 插入内容
<record model="ir.ui.view" id="view_partner_form3">
<field name="name">res.partner.form.inherit3</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="lang" position="before">
<field name="relation_ids" />
</field>
<field>
</record>
<record model="ir.ui.view" id="view_partner_form4">
<field name="name">res.partner.form.inherit4</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="lang" position="after">
<field name="relation_ids" />
</field>
<field>
</record>
# 修改属性:修改属性能实现的功能,不要使用replace
<xpath expr="//field[@name='name']"position="attributes">
<attribute name="required">1</attribute>
</xpath>
# 多变化
<record model="ir.ui.view" id="view_partner_form5">
<field name="name">res.partner.form.inherit5</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="lang" position="replace"/>
<field name="website" position="after">
<field name="lang" />
</field>
<field>
</record>
# xpath的节点
<record model="ir.ui.view" id="view_partner_form6">
<field name="name">res.partner.form.inherit6</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<data>
<xpath expr="/feild[@name='address']/form/field[@name='email']"
position="after">
<field name="age" />
</xpath>
<xpath expr="/field[@name='address']/tree/field[@name='email']"
position="after">
<field name="age" />
</xpath>
</data>
<field>
</record>
* 窗口操作(视图动作)
如下一些代码
<?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="type">ir.actions.act_window</field>
<field name="domain">["list of 3-tuples (max 250 characters)"]</field>
<field name="context">{"context dictionary (max 250 characters)"}</field>
<field name="res_model">todo.task.stage</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field> 这里表示有两个视图可用,且先tree,后form, 若只有tree, 则后面点列表是没反应的
<field name="search_view_id" ref="todo_task_search"/>
<field name="view_id" ref="view_form_todo_task_ui" />
</record>
窗口的动作是存在 ir.actions.act_window 模型中的,我们可以在xml文件中用<act_window>来快捷定义
下面是部分属性说明,完整的可以在 openerp/addons/base/ir/ir_actions.py 中的 ir.actions.act_window
类中可以找到
# name 显示的标题
# type 动作类型 ,默认ir.actions.act_window
# view_id 中的 ref 值是对应视图对象的id 触发时用哪个视图
# context 设置目标视图的上下文
比如:<field name="context">{'search_default_group_by_product': True, 'search_default_group_by_location': True}</field>
<!--默认搜索 以产品分组 和以库位分组-->
# domain 过滤记录按条件,如:[["customer", "=", true]]
# res_id: 当动作打开视图是表单视图时,要指定的加载记录id,只有‘view_mode’ 值为 form时才有效
否则就会新建一个记录 如:"res_id": a_product_id,
# res_model 动作响应的目标模型
# target 如果设置为new 就打开新窗口,默认是 current
# view_mode:列出允许使用的视图模式 如 form, tree, calendar,etc 默认是 tree,form
# view_type:设定tree时的列表是树状还是普通列表, tree-树状 form-普通列表 缺省是form
# usage: 过滤菜单和动作
# view_ids:
# views:是(view_id,view_type) 元组对列表,第一组是动作默认打开的视图
如:"views": [[False, "tree"], [False, "form"]]
# limit 指列表视图时,一页的记录数,默认是80
# auto_refresh: 在视图中添加一个刷新功能
# groups_id:权限组
# search_view_id 指定响应的搜索视图(id,name) 元组对
# filter:列表视图显示过滤器(bool)
# auto_search: 加载默认视图后,自动搜索
# src_model 指定可以启动视图的更多按钮
# multi 设为True, 更多按钮显示在列表视图,否则显示在表单视图
系统的默认值:
_defaults = {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'tree,form',
'context': '{}',
'limit': 80,
'target': 'current',
'auto_refresh': 0,
'auto_search':True,
'multi': False,
}
* 菜单项
如下一些代码
<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>来快捷定义
openerp/addons/base/ir/ir_ui_menu.py
# id 菜单的唯一id用于父子级别和调用
# name 在视图中显示的名字 如果定义的 action,这个可以省略,会用对应action
的name值
# sequence 显示排序
# parent 本菜单的父菜单,子菜单都要指定,只有顶级菜单不要指定
# action 本菜单的连接动作
# groups 指定权限组,用户组的extraID
这里的action 要关联到视图动作定义中的id
如 action="action_todo_stage 对应视图动作中的 id="action_todo_stage"
注:在定义菜单和窗体动作时,一定要注意一下顺序,先定义菜单对应的窗体动作
如:
<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"/>
* 在中间“更多”按钮加动作
<record id="action_sale_order_make_invoice" model="ir.actions.act_window">
<field name="name">Make Invoices</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.make.invoice</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_sale_order_make_invoice"/>
<field name="target">new</field>
<field name="multi">True</field>
</record>
<record model="ir.values" id="sale_order_make_invoice">
<field name="model_id" ref="sale.model_sale_order" />
<field name="name">Make Invoices</field>
<field name="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_sale_order_make_invoice'))" />
<field name="key">action</field>
<field name="model">sale.order</field>
</record>
重点讲第二段
@model_id 对应的值是所在那个模型中加 格式[模块名].model_模型名 用_连起来,若是本模块,可以省了[模块名].
视图上采用ref 引用模型都是这种格式
@name 定的名称
@key2 动作多窗口
@value 引用一个已定义的窗体动作来完成
@key 产生的类型,这里是动作
@model作用在的模型
* 三个主要的视图 list或 tree(树状)视图, 表单form视图, search搜索视图 对应模型 ir.ui.view
在openerp/addons/base/ir/ir_ui_view.py 中可以看到有 tree, form, graph, calendar, diagram
gantt,kanban, search,qweb 这些视图
定义视图的总框架:
<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>
arch 字段一定要申明 type为xml 否则无法解析
* 表单视图
# 添加在动作和菜单项后面 <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>上
-------------------------
<header>
<field name="state" widget="statusbar"
statusbar_visible="draft,sent,progress,invoiced,done"
statusbar_colors="{'shipping_except':'red','waiting_date':'blue'}"/>
</header>
@ 加入状态挂件
# 元素功能分组排列
group 分组的性性
@ colspan 说明该控件占用父容器多少列 openerp form 为顶级容器,约定为4列
colspan 缺省是 2
@ rowspan 行数
@ expand
@ col 用于容器控件,如group 表不这个容器内部分几列
@ string 组的名称
@ openerp 控件一般都有lable 这样占两列
@ class 加载对应的类名用于定位
举一例:
①<group col="6" colspan='4'>
②<group col="2" colspan="4">
<separator colspan="2" string="Product Description"/>
<field name="name" select="1">
<field groups="base.group_extended" name="variants" select="2" />
</group>
③<group col="2" colspan="1">
<separator colspan="2" string="Codes"/>
<field name="default_code" select="1">
<field groups="base.group_extended" name="ean13" select="2" />
</group>
④<group col="2" colspan="1">
<separator colspan="2" string="Product Type"/>
<field name="sele_ok" select="2">
<field name="purchase_ok" select="2">
<field groups="base.group_extended" name="rental" select="2" />
</group>
</group>
① colspan="4" 占据了整行,col="6" 表示①这个组控件内分为6列
② col="2" 表示②这个组控件内分为2列, colspan="4" 表示占①组控件4列
③ col="2" 表示③这个组控件内分为2列, colspan="1" 表示占①组控件1列
④ col="2" 表示④这个组控件内分为2列, colspan="1" 表示占①组控件1列
注:
加了<group>...</group>, 里面的field会自动加上<label>
<group>顶级是默认里面分为4列
<group>子级里面默认是2列,这样<label>占一列,<field>值占一列
<group>里面的field不要加<label>要指明,如:
<group string="Source Term">
<field name="source" nolabel="1" height="400"/>
</group>
group 也有对应的class,可以用于定位,如(右下角):
<group class="oe_subtotal_footer">
<field name="amount_untaxed"/>
<field name="amount_tax"/>
<field name="amount_total" class="oe_subtotal_footer_separator"/>
<field name="residual" style="margin-top: 10px"/>
</group>
# 有时<sheet>之间的内容采用html来布局会更灵活
如:
<sheet>
<div class="oe_title">
<label for="name" class="oe_edit_only" string="Idea Name" />
<h1><field name="name" /></h1>
</div>
<separator string="General" colspan="2" />
<group colspan="2" col="2">
<field name="description" placeholder="Idea description..." />
</group>
</sheet>
<field name="product_image" widget="image" class="oe_avatar oe_right"/>
# notebook 是标签块
@string tab的标签名
@accesskey
@attrs
# newline
# separator 分割线
# header 头部
* 视图元素
#按钮<button>,支持的属性
icon 可用的icon在 addons/web/static/src/img/icons
string 按钮的显示文字
type 值可以是 workflow, object action
name 就是要触发的方法标识
args 传递方法的参数
content 上下文
confirm 针对对话框的确认
special="cancel" 用于向导
states 可见的状态
classname 加载的类名(常用 oe_highlight)
例子:
<footer>
<button name="act_update" string="Update" type="object" class="oe_highlight"/>
or
<button special="cancel" string="Cancel" type="object" class="oe_link"/>
</footer>
#字段<field>,支持的属性
name 字段技术名
string 显示名
help 帮助提示
placeholder 占位文字
widget 小物件 后面常用值(progress, many2onebutton, handle, statusbar, image, many2many_tags, selection)
options 小物件对应的选项,
class 加载类名
(常用的
oe_inline
oe_left
oe_right
oe_read_only
oe_edit_only
oe_no_button
oe_avatar 图片字段用
)
invisible="1" 标识不可见
groups 指定权限的可见 后面的值一般为 用户组或用户名
nolabel="1" 不显示标签,会用于<group>之内
readonly="1" 标识只读
required="1" 标识不能为空
on_change 这是旧版的,新版用@api.change(self)来处理
domain 条件过滤(仅用于关联字段)
context 上下文(仅用于关联字段)
required 必填
placeholder 占位的字符
mode 用于 One2many (有值 tree, form, kanban, graph 默认是tree)
help 字段的提示信息
sum,avg 小计,平均值
password="True" 密码框
filename 文件上传用
attrs 后面是表达式
# 标签
<label>
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
#关联字段
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')
举例说明:
视图中定义如下:
<!-- content of form view -->
<field name="amount"/>
<field name="unit_price"/>
<field name="price" readonly="1"/>
对应模型中的定义如下:
# onchange handler
@api.onchange('amount', 'unit_price')
def _onchange_price(self): #当用api.onchange时 self为记录,不是记录集
# set auto-changing field
self.price = self.amount * self.unit_price
# Can optionally return a warning and domains
return {
'warning': {
'title': "Something bad happened",
'message': "It was very bad indeed",
}
}
这样只要 amount 或 unit_price 字段的值变化,对应的price值跟着变化
注:只支持简单字段,像many2one, one2many 这些字段不支持
若要指定在那个字段去触发,则在视图中定义
<field name="name" on_change="0"/>
on_change="0"
* 动态视图
# 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 设置字段在列表直接可以编辑
例:<tree string="Translations" editable="top">
colors 按条件设定记录的颜色
<tree string="Idea Categories" colors="blue:state=='draft';red:state=='trashed'">
<field name="name"/>
<field name="state"/>
</tree>
default_order 指定列表记录的排序条件字段
<tree default_order="sequence,name desc">
toolbar 设置为True,会显示层次结构像菜单一样
fonts 按条件设定记录的字体
create,delete,edit 若设置为false 则为不可用
string :视图的标签,是可以翻译的
允许元素:
field, group, separator, tree, button, filter, newline
# 当不要创建和编辑功能时,在<tree> 加上 create="0"
看一下树状列表,以产品分类为例:
<record id="product_category_tree_view" model="ir.ui.view">
<field name="name">product.category.tree</field>
<field name="model">product.category</field>
<!--父子 -->
<field name="field_parent">child_id</field>
<field name="arch" type="xml">
<tree toolbar="True" string="Product Categories">
<field name="name"/>
</tree>
</field>
</record>
<!--产品分类动作 -->
<record id="product_category_action" model="ir.actions.act_window">
<field name="name">Products by Category</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.category</field>
<field name="domain">[('parent_id','=',False)]</field>
<!--采用树状-->
<field name="view_type">tree</field>
<field name="view_id" ref="product_category_tree_view"/>
<field name="help" type="html">
<p>
Here is a list of all your products classified by category. You
can click a category to get the list of all products linked to
this category or to a child of this category.
</p>
</field>
</record>
@可以看到:<field name="view_type">tree</field>
@视图中用到 <field name="field_parent">child_id</field>
* 搜索视图
代码如下(产品模板的搜索视图):
<record id="product_template_search_view" model="ir.ui.view">
<field name="name">product.template.search</field>
<field name="model">product.template</field>
<field name="arch" type="xml">
<search string="Product">
<!--产品搜索-->
<field name="name" string="Product" filter_domain="['|',('default_code','ilike',self),('name','ilike',self)]"/>
<!--过滤-->
<filter string="Services" icon="terp-accessories-archiver" domain="[('type','=','service')]"/>
<filter string="Consumable" name="consumable" icon="terp-accessories-archiver" domain="[('type','=','consu')]" help="Consumable products"/>
<separator/>
<!--可销售-->
<filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
<!--产品分类-->
<field name="categ_id" filter_domain="[('categ_id', 'child_of', self)]"/>
<field string="Product Variant" name="product_variant_ids" filter_domain="['|', ('product_variant_ids.name','ilike',self), ('product_variant_ids.attribute_value_ids.attribute_id.name','ilike',self)]"/>
<!--公司-->
<field name="company_id"/>
<!--价格表-->
<field name="pricelist_id" widget="selection" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/> <!-- Keep widget=selection on this field to pass numeric `self` value, which is not the case for regular m2o widgets! -->
<group expand='0' string='Group by...'>
<!--分类-->
<filter string='Category' domain="[]" context="{'group_by' : 'categ_id'}"/>
<!--默认计量单位-->
<filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'uom_id'}"/>
<!--类型-->
<filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
</group>
</search>
</field>
</record>
# <search>
上面用于搜索字段 name default_code
field元素定义的属性
name 字段标识名
string 标签名
operator 操作符
filter_domain 对应字段如何对输入内容搜索
上面的例子基于name字段搜索时,输入框内容和 name 和 default_code都比较
有一个满足就可以
context 添加上下文
groups 指定用户权限可见
widget 物件(selection 仅为 Many2one 字段)
domain 过滤条件(用于Mnay2one字段)
filter元素支持属性(过滤器)
name 指定动作标识符 (在模型中会定义的方法名)
string 标签名
domain 过滤记录按条件
content 上下文
helper 提示信息
groups 指定用户权限可见
icon 小图标
separator 用于分隔
group 用于分组
它的单项类似filter,但重点用了context来分组
* 日历视图
<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_stop 结束日期
date_delay 延期
color 用颜色的实体
event_open_popup 用弹出容器代替表单视图
quick_add
all_day 总天数
display 显示文字
attendee 出席人
* 甘特视图
<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_stop 结束日期
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>
type:bar(默认),pie,line,pivot 图形类别
stacked: 仅用于 bar
orientation:horizontal,vertical 方向:水平 垂直
字段支持的属性<field>
name 字段标识名
type 分组方式,默认是row 行 ,设定可以是col列,measure
interval 时间度量 day,week,month,quarter 或 year
* 看板
todo_task.py
-----------------------------
# -*- coding: utf-8 -*-
from openerp import models, fields
class TodoTask(models.Model):
_inherit = 'todo.task'
priority = fields.Selection(
[('0', 'Low'), ('1', 'Normal'), ('2', 'High')],
'Priority', default='1')
kanban_state = fields.Selection(
[('normal', 'In Progress'),
('blocked', 'Blocked'),
('done', 'Ready for next stage')],
'Kanban State', default='normal')
----------------------------------
todo_view.xml
----------------------------------
<?xml version="1.0"?>
<openerp>
<data>
<!-- Add Kanban view mode to the menu Action: -->
<act_window id="todo_app.action_todo_task"
name=" To-Do Tasks"
res_model="todo.task"
view_mode="kanban,tree,form,calendar,gantt,graph"
context="{'search_default_filter_my_tasks': True}"/>
<!-- Add Kanban view -->
<record id="To-do Task Kanban" model="ir.ui.view">
<field name="name">To-do Task Kanban</field>
<field name="model">todo.task</field>
<field name="arch" type="xml">
<!-- Empty for now, but the Kanban will go here! -->
<kanban>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_vignette">
<img t-att-src="kanban_image('res.partner','image_medium', record.id.value)"
class="oe_kanban_image"/>
<div class="oe_kanban_details">
<!-- Title and Data content -->
<h4>
<a type="open">
<field name="name"/>
</a>
</h4>
<field name="tags"/>
<ul>
<li>
<field name="user_id"/>
</li>
<li>
<field name="date_deadline"/>
</li>
</ul>
<field name="kanban_state" widget="kanban_state_selection"/>
<field name="priority" widget="priority"/>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
</data>
</openerp>
----------------------------------
# 可用属性
default_group_by 默认分组
default_order 默认排序字段
class 类名
quick_create
可加载的字元素属
field字段
name 名称 sum,avg,min, max, count
template 是一个qweb模板
instance widget record read_only_mode
# 看板视图的风格
Vignette 就是左边有一个小插件,在系统中常用于 客户、产品、等
Card 常用于 CRM中的机会和商机,也用在项目任务
# 看板视图
<kanban> 顶级元素
常用两个字段 priority , kanban_state
priority 显示项目的紧急程度
kanban_state 显示项目的各阶段
<templates> 主要有一个命名 kanban-box 采用下面的元素 <t t-name="kanban-box">...</t>
<field>这是字段,若是只是用于表达,就放在<templates>之前,字段具有聚合性如:
<field name="effort_estimated" sum="Total Effort" />
<kanban> 顶级元素支持一些属性
default_group_by 默认分组条件
default_order 默认排序条件
quick_create="false" 不能快速创建选项
class 加入css类
css类,有两个主要的 oe_kanban_vignette 和 oe_kanban_details
<img>中的 t-att-src 可以计算图片的src存在数据库中的值
# 在看板视图中的动作
在<a>中有 type 属性 像 <button>里面的功能似的
type的值有:
open: 打开表单视图
edit: 打开并编辑表单视图
delete: 删除记录
#卡片风格的看板视图
示例代码:
<t t-name="kanban-box">
<div class="oe_kanban_card">
<div class="oe_dropdown_kanban oe_dropdown_toggle">
<!-- Top-right drop down menu -->
</div>
<div class="oe_kanban_content">
<!-- Option menu will go here! -->
<h4>
<a type="open">
<field name="name"/>
</a>
</h4>
<field name="tags"/>
<ul>
<li>
<field name="user_id"/>
</li>
<li>
<field name="date_deadline"/>
</li>
</ul>
<div class="oe_kanban_bottom_right">
<field name="kanban_state"
widget="kanban_state_selection"/>
</div>
<div class="oe_kanban_footer_left">
<field name="priority" widget="priority"/>
</div>
</div>
</div>
</t>
* 综合来一例
# 模型 lesson.py
# -*- coding: utf-8 -*-
from openerp import models, fields
class oecn_training_lesson(models.Model):
_name = 'oecn.training.lesson'
_description = u'OECN 培训课程'
_columns = {
'name':fields.char( u'课程名',size=64,select=True),
'date_start':fields.date(u'开始日期',select=True),
'total_day':fields.float(u'总天数',digits=(16,1)),
'teacher':fields.many2one('res.users',u'授课老师'),
'students':fields.many2many('res.partner',string=u'学生'),
'price':fields.float(u'价格',digits=(16,2)),
}
u后面再加中文,这样不会乱码,显性指明编码
#视图lesson_view.xml
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--定义表单视图-->
<record model="ir.ui.view" id="oecn_training_lesson_form_view">
<field name="name">课程表单</field>
<field name="type">form</field>
<field name="model">oecn.training.lesson</field>
<field name="arch" type="xml">
<form>
<group>
<field name="name"/>
<field name="date_start"/>
<field name="total_day"/>
<field name="price"/>
<field name="teacher"/>
<field name="students" colspan="4"/>
</group>
</form>
</field>
</record>
<!--定义列表视图-->
<record model="ir.ui.view" id="oecn_training_lesson_tree_view">
<field name="name">课程列表</field>
<field name="type">tree</field>
<field name="model">oecn.training.lesson</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="date_start"/>
<field name="teacher"/>
<field name="price" sum="合计"/>
</tree>
</field>
</record>
<!--定义视图动作-->
<record model="ir.actions.act_window" id="action_oecn_training_lesson">
<field name="name">课程</field>
<field name="res_model">oecn.training.lesson</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="oecn_training_lesson_tree_view"/>
</record>
<!--定义菜单-->
<menuitem id="oecn_menu" name="OECN"/>
<menuitem id="oecn_training_menu" name="OECN Training" parent="oecn_menu"/>
<menuitem id="oecn_training_lesson_menu" name="OECN Training Lesson" parent="oecn_training_menu"
action="action_oecn_training_lesson"/>
</data>
</openerp>
这样从菜单到响应完成,打开展开一个表单视图
视图动作到了8.0可以用采用 <act_window>标签来简写
====================================
接着继承插件写法,给课程分配教室
# 模型 lesson.py
# -*- coding: utf-8 -*-
from openerp import models, fields
class oecn_training_lesson(models.Model):
_inherit = 'oecn.training.lesson'
_columns = {
'classroom_id':fields.many2one('oecn.training.classroom','教室'),#添加一个教室属性,为多对一对象。
}
教室模型 classroom.py
# -*- coding: utf-8 -*-
from openerp import models, fields
class oecn_training_classroom(models.Model):
_name = 'oecn.training.classroom'
_description = u'OECN 教室'
_columns = {
'number':fields.char(u'编号', size=64, select=True),
'capacity':fields.integer(u'容纳人数', select=True),
'location':fields.char(u'地点', size=125, select=True),
}
#视图lesson_view.xml
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--OECN 教室-->
<record model="ir.ui.view" id="oecn_training_lesson_from_inherit_classroom_view">
<field name="name">课程教室继承视图</field>
<field name="type">form</field>
<field name="model">oecn.training.lesson</field>
<field name="inherit_id" ref="oecn_training.oecn_training_lesson_form_view"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="classroom_id"/>
</field>
</field>
</record>
</data>
</openerp>
<field name="inherit_id" ref="oecn_training.oecn_training_lesson_form_view"/>
这句就是继承,ref指名要继承的视图id
后面就找位置
<field name="name" position="after">
<field name="classroom_id"/>
</field>
意思是在要继承的视图的name字段后(position="after"),添加一个教室字段。
# 教室的视图
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--OECN 教室-->
<record model="ir.ui.view" id="oecn_training_classroom_from_view">
<field name="name">教室</field>
<field name="type">form</field>
<field name="model">oecn.training.classroom</field>
<field name="arch" type="xml">
<field name="number"/>
<field name="capacity"/>
<field name="location" />
</field>
</record>
<!--定义列表视图-->
<record model="ir.ui.view" id="oecn_training_classroom_tree_view">
<field name="name">教室列表</field>
<field name="type">tree</field>
<field name="model">oecn.training.classroom</field>
<field name="arch" type="xml">
<field name="number"/>
<field name="capacity"/>
<field name="location" />
</field>
</record>
<!--定义视图动作-->
<record model="ir.actions.act_window" id="action_oecn_training_classroom">
<field name="name">教室</field>
<field name="res_model">oecn.training.classroom</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="oecn_training_classroom_tree_view"/>
</record>
<menuitem id="oecn_training_classroom_menu" name="OECN Training Classroom"
parent="oecn_training.oecn_training_menu" action="action_oecn_training_classroom"/>
</data>
</openerp>
* 代码分析时有用点
<!--仅在编辑时显示标签-->
<label for="name" class="oe_edit_only"/>
<!--多公司时显示公司名-->
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
* css的运用
oe_grey:灰色
<p class="oe_grey">Select the places where this route can be selected</p>
* 设置context的值
<filter name="show_inactive" string="Show inactive" context="{'active_test': False}" />
这样表示,不测试 active这个字段 显示列表数据,系统默认所有在列表时,若有active这个字段
显示是都是 active 为t时才能显示出来
<field name="name" context="{default_name:'hello'}" /> 设置默认值
相关文章
发表评论
评论列表
- 这篇文章还没有收到评论,赶紧来抢沙发吧~