视图和事件

介绍视图

因为程序中所有数据存储在对象中,这个在对象的部分已经解释过了,这些对象如何显示给用户的呢?我们将在这个部分解释这个问题。

首先注意每个资源类型有自己的界面。例如,修改一个合作伙伴数据的显示不同于修改invoice。

然后,你应该知道Openerp用户界面是动态变化的,这意味着它不是有“静态”代码来描述,而是由XML动态描述用户界面。

从现在起,我们称这些为screen descriptions views。

这些视图的显著特征是可以在任何时刻被修改(即使是在程序执行时刻)。如果对一个已经显示的视图进行修改后,你只需要关闭这个视图的标签,并且再打开,修改后的视图就会显示。

视图原理

视图描述了每个对象是如何显示的。更准确的说,对每个对象,我们可以定义一个或几个视图来描述哪个字段要显示和如何显示。

视图有两种:

  1. form views
  2. tree views

Note

Since OpenERP 4.1, form views can also contain graphs.

Form 视图

在表单视图中,字段配置一致遵守相同的准则。显示的字段遵守以下的准则:

  • 默认情况下,每个字段由label开始,以字段名称代表该字段。
  • 字段在屏幕上按照从左到右,从上到下的顺序显示,是依照他们在视图中的显示顺序。
  • 每个屏幕分成4列,每一列要么是一个label,要么是“edition”字段。每个edition字段由label开始(默认情况下),以字段名称代表该字段,在屏幕的每一行将有两个字段。下面的截图中,绿色和红色的区域正好举例说明了这4列,他们分别代表着labels和他们相关的字段。
../../_images/sale_order.png

视图支持更多的高级选项:

  • 一个视图字段可以有多列。例如,下面的截图中,蓝框的区域事实上是一个“one to many”的字段。我们注意到该字段是整个屏幕的宽度,而不是一列。
../../_images/sale_order_sale_order_lines.png
  • 我们同样可以做相反的操作:将一列分成任意的多列。上图中的绿框区域正好就说明这个情况。更准确的说,绿框看着是两列,其实包括着4列。

下面截图中蓝色的区域,是将对象的字段分成不同的标签。

../../_images/sale_order_notebook.png

Tree 视图

当我们工作在一个list样式下(想要同时看到很多资源)和查询界面时,这些视图就会用到。这些视图比form views简单,有较少的选项。

../../_images/tree_view.png

Graph 视图

graph对所有的表单视图来说是一种新形式的视图。例如,如果一个销售订单线作为list或graph必须是可见的,将它定义为打开这个销售订单线的动作。不要将视图形式设置为“tree,form,graph”或“form,graph”,必须设置为“graph,tree”来首先显示graph或者设置为“tree,graph”来首先显示list。(这个视图形式是你的“form,tree”视图的额外形式并且应该有个分开的菜单选项)。

<field name="view_type">form</field>
<field name="view_mode">tree,graph</field>

view_type:

tree = (tree with shortcuts at the left), form = (switchable view form/list)

view_mode:

tree,graph : sequences of the views when switching

接下来,用户可以从一个视图转换到另一个视图。不像表单和列表视图一样,OpenERP不能自动按需创建graph视图,所以你必须自己定义graph视图:

<record model="ir.ui.view" id="view_order_line_graph">
   <field name="name">sale.order.line.graph</field>
   <field name="model">sale.order.line</field>
   <field name="type">graph</field>
   <field name="arch" type="xml">
         <graph string="Sales Order Lines">
              <field name="product_id" group="True"/>
              <field name="price_unit" operator="*"/>
        </graph>
    </field>
</record>

graph 视图

graph类型的视图只是graph的字段列表。

Graph tag

graph的默认类型是圆形分格统计图表(pie chart),要将它转换成条形图(barchart),就需要将<graph string=”Sales Order Lines”> 转换成 <graph string=”Sales Order Lines” type=”bar”>,你也可以改变方向。

:例如 :

<graph string="Sales Order Lines" orientation="horizontal" type="bar">

Field tag

第一个字段是x轴,第二个是y轴,第三个是z轴,这个是可选择的三维图字段。你可以运用一些属性到每个field/axis。

  • group: 如果设置为true,客户端会组合这个字段相同值的所有项。对于相互的字段,它会应用operator。
  • operator: operator的应用是由另一个字段决定的,默认是“+”,允许的值是:
  • +: addition
  • *: multiply
  • **: exponent
  • min: minimum of the list
  • max: maximum of the list
Defining real statistics on objects:
 

定义真正的对象数据统计:

  1. 定义一个统计对象,它是PostgreSQL视图
  2. 在这个对象上创建一个tree view和graph view

You can get an example in all modules of the form: report_.... Example: report_crm.

Search views

search views是Openerp 6.0版本支持的一个新特性。它创建一个自定义的查找面板,它的显示和表单视图非常相似,除了将视图的类型和根元素由form改为search。

../../_images/search.png

下面是search视图中要用到的新的元素和特性列表。

Group tag

不像表单元素组,search view groups支持一行中不限数量的widget(fields或filters),并且只是使用下面的属性:

  • expand: turns on the expander icon on the group (1 for expanded by default, 0 for collapsed)
  • string: label for the group
<group expand="1" string="Group By...">
   <filter string="Users" icon="terp-project" domain="[]" context="{'group_by':'user_id'}"/>
   <filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>
   <separator orientation="vertical"/>
   <filter string="Deadline" icon="terp-project" domain="[]" context="{'group_by':'date_deadline'}"/>
</group>

以上的截图是个扩展group。

Filter tag

Filters在查找面板作为一个触发按钮方式显示,可以添加新的过滤元素在当前域或是查询视图的上下文。Filters可以作为一个字段子元素添加进去,来表示他们专门用于该字段(这种情况下button按钮会变小些)。

在图中表单上部红色区域包含着filters,而蓝色区域是一个字段,并且是child filter。

<filter string="Current" domain="[('state','in',('open','draft'))]" help="Draft, Open and Pending Tasks" icon="terp-project"/>
<field name="project_id" select="1" widget="selection">
    <filter domain="[('project_id.user_id','=',uid)]" help="My Projects" icon="terp-project"/>
</field>

Group By

<filter string="Project" icon="terp-project" domain="[]" context="{'group_by':'project_id'}"/>

以上的filters groups records都用相同的project_id值。groups懒加载,所以,inner records只在group扩展时加载。group header lines包含这个group中所有记录的共同值,并且所有数字型的字段一般先是在视图中,来代替值的和。

将指定的a list of fields的很多值分组来代替a single string是可能的。这种情况下,嵌套分组就会显示出来:

<filter string="Project" icon="terp-project" domain="[]" context="{'group_by': ['project_id', 'user_id'] }"/>

Fields

search view里面的字段元素用来为搜索得到user-provided值。其结果是,对于组元素(group elements),它们和表单视图的字段大不相同:

  • 一个搜索字段可以包含过滤(filters),通常表明字段和过滤管理相同的字段并且二者相关。
那些内部的过滤器渲染为小buttons,紧挨着字段,肯定没有string属性。
  • 一个search字段确实构造了一个由[(field_name, operator, field_value)]构成的domain。这个domain在两种情况下无效:
  • @operator replaces the default operator for the field (which depends on its type)
  • @filter_domain lets you provide a fully custom domain, which will replace the default domain creation
  • 一个search字段不能默认创建上下文,但是你可以提供一个context,来评估和合并进wider context。

为了在你的context或filter_domain中获得字段值,你可以使用可变的self:

<field name="location_id" string="Location"
       filter_domain="['|',('location_id','ilike',self),('location_dest_id','ilike',self)]"/>

or

<field name="journal_id" widget="selection"
       context="{'journal_id':self, 'visible_id':self, 'normal_view':False}"/>

Range fields (date, datetime, time)

range字段由两个input widgets组成,而不是之前的一个。

这导致了它的特殊性(相比于non-range search fields来说):

  • 由于domain由两个section构成,每个section使用不同的operator,但通过@operator重写range field是不可能的。
  • Instead of being a simple value (integer, string, float) self for use in @filter_domain and @context is a dict.
因为range field的每个input widget可以为空(并且字段本身始终有效),必须谨慎使用self:它有两个string keys“from”和“to”,这些keys任意一个可以不使用或设置其值为False。

Actions for Search view

在声明一个search view后,它会被自动用在相同model的所有tree view中。如果一个model有几个search view,那它会使用拥有最高优先级的那个。另一个选择就是通过设置action中的search_view_id字段来明确选择想要使用的search view。

除了能够传递在action上下文中的默认表单值外,OpenERP 6.0现在支持通过上下文来传递search views的初始值。这个上下文keys需要匹配search_default_XXX格式。在search view中XXX是指<field>或<filter>的名字(其实对于filters,name属性并不是必须的,当它必须要有个明确的name值时才起作用)。这个值要么是search fields的初始值,要么是filter的布尔值,现在来切换它们:

<record id="action_view_task" model="ir.actions.act_window">
    <field name="name">Tasks</field>
    <field name="res_model">project.task</field>
    <field name="view_type">form</field>
    <field name="view_mode">tree,form,calendar,gantt,graph</field>
    <field eval="False" name="filter"/>
    <field name="view_id" ref="view_task_tree2"/>
    <field name="context">{"search_default_current":1,"search_default_user_id":uid}</field>
    <field name="search_view_id" ref="view_task_search_form"/>
</record>

Custom Filters

对于V6.0,search view都可以进行自定义search filters,向下面显示的那样。用户可以使用当前模块的任意字段来定义自己的filters,并且用AND/OR operator来合并他们。将任何的search context作为个人过滤器都是可以的,还可以在任何时候重新调用。过滤器可以在用户主页直接转换成快捷键。

../../_images/filter.png

在以上的截图中,我们过滤Partner用Salesman = Demo user 和Country = Belgium,我们将这个搜索标准作为快捷键或是保存为过滤器。

过滤器是用户特定的,可以通过在filters 下拉菜单中管理过滤器选项来进行修改。

Calendar Views

Calendar 视图为数据提供时间线(timeline)/日程表(schedule)视图。

View Specification

这有一个视图例子:

<calendar color="user_id" date_delay="planned_hours" date_start="date_start" string="Tasks">
    <field name="name"/>
    <field name="project_id"/>
</calendar>

下面是该视图标签的属性:

string
该视图的标题

date_start :表示开始时间的属性,该字段是必须的。 date_stop :表示结束时间的属性,如果指定了date_delay属性就可以忽视该属性。 date_delay :A numeric field to specify time in hours for a record. This attribute will get preference over date_stop and date_stop will be ignored. day_length :显示工作时间长度的数字值,默认为8小时 color :A field, generally many2one, to colorize calendar/gantt items. mode :A string value to set default view/zoom mode. For calendar view, this can be one of following (default is month):

  • day
  • week
  • month

Screenshots

Month Calendar:

../../_images/calendar_month.png

Week Calendar:

../../_images/calendar_week.png

Gantt Views

Gantt view为数据提供时间线视图,总体来说,它用于显示项目任务和资源分配。

甘特图是这个项目所有任务的图形显示。图的每一条显示该任务花费时间的长度。

资源分配总条在图中所有任务的上面显示,代表着任务中资源的有效利用情况。

颜色使用情况是:

  • Gray 显示是指这个时候资源没有分配给任何任务。
  • Blue 显示是指这个时候资源完全分配了。
  • Red 显示是指这个时候资源overallocated。

View Specification

Here is an example view:

<gantt color="user_id" date_delay="planned_hours" date_start="date_start" string="Tasks">
    <level object="project.project" link="project_id" domain="[]">
        <field name="name"/>
    </level>
</gantt>

甘特图标签的属性和calendar图标签的属性类似。level标签用于将一些many2one字段的记录分组。目前仅支持one level。

下面是gantt标签的属性:

string
The title string for the view.
date_start
A datetime field to specify the starting date for the gantt item. This attribute is required.
date_stop
A datetime field to specify the end date. Ignored if date_delay attribute is specified.
date_delay
A numeric field to specify time in hours for a record. This attribute will get preference over date_stop and date_stop will be ignored.
day_length
An integer value to specify working day length. Default is 8 hours.
color
A field, generally many2one, to colorize calendar/gantt items.
mode

A string value to set default view/zoom mode. For gantt view, this can be one of following (default is month):

  • day
  • 3days
  • week
  • 3weeks
  • month
  • 3months
  • year
  • 3years
  • 5years

The level tag supports following attributes:

object
一个openerp对象和视图object有many2one的关系。
link
链接到给定对象的当前对象的字段名
domain
这个domain用于过滤给定的对象记录。

Drag and Drop

左边的窗格显示由level分组的任务列表。你可以重新排序或是通过拖动他们来更改记录的分组。

主要内容窗格显示在时间格中绘制的水平条。一组水平条概要汇总了所有任务资源分配条。

你可以通过水平拖动任务来更改任务开始时间,当然也可以通过拖动右侧条来更改结束时间。

Note

The time is calculated considering day_length so a bar will span more then one day if total time for a task is greater then day_length value.

Screenshots

../../_images/gantt.png

Design Elements

文件中的视图描述形式如下:

Example:
<?xml version="1.0"?>
<openerp>
   <data>
       [view definitions]
   </data>
</openerp>

视图定义包含了以下三种类型的标签:

  • <record> 标签有属性model=“ir.ui.view”,它包含本身的视图定义
  • <record> 标签有属性model=“ir.actions.act_window”,它将动作和这些视图链接起来。
  • <menuitem> 标签,在菜单中创建记录,将他们和动作链接起来。

New:你可以指定组,菜单在menuitem标签中用组属性来访问这些组。

New:你可以使用shortcut标签来加快捷键。

Example:
<shortcut
    name="Draft Purchase Order (Proposals)"
    model="purchase.order"
    logins="demo"
    menu="m"/>

你应该加一个id属性在menuitem上

<record model="ir.ui.view" id="v">
    <field name="name">sale.order.form</field>
    <field name="model">sale.order</field>
    <field name="priority" eval="2"/>
    <field name="arch" type="xml">
            <form string="Sale Order">
                .........
            </form>
    </field>
</record>

priority字段的默认值为16,在没有特别规定的前提下,系统的视图都是最低优先级。

View Types

Tree View

你可以指定列表中包含的列元素和一些细节在列的显示中。search字段不能在这指定,他们显示在form视图中。

<record id="view_location_tree2" model="ir.ui.view">
    <field name="name">stock.location.tree</field>
    <field name="model">stock.location</field>
    <field name="type">tree</field>
    <field name="priority" eval="2"/>
    <field name="arch" type="xml">
        <tree
                colors="blue:usage=='view';darkred:usage=='internal'">

            <field name="complete_name"/>
            <field name="usage"/>
            <field
                name="stock_real"
                invisible="'product_id' not in context"/>
            <field
                name="stock_virtual"
                invisible="'product_id' not in context"/>
        </tree>
    </field>
</record>

这个例子是一个二维列表,但是你可以通过指点field_parent来显示树结构。这个名字尽管有些误导人,但是该字段必须包含一列所有的child记录。

<record id="view_location_tree" model="ir.ui.view">
    <field name="name">stock.location.tree</field>
    <field name="model">stock.location</field>
    <field name="type">tree</field>
    <field name="field_parent">child_ids</field>
    <field name="arch" type="xml">
        <tree toolbar="1">
            <field icon="icon" name="name"/>
        </tree>
    </field>
</record>

在tree元素中包含下面的属性:

colors:在列表中根据不同情况不同的颜色来记录,默认为黑。 toolbar:如果你想要一个树结构在单独工具栏区域列出上层的记录,那就把给属性值设为1。当你点击工具栏上的一个记录时,它的所有的后代都会显示在main tree中。二维列表中该值可以忽略

Grouping Elements

Separator

加个分隔线

Example:
<separator string="Links" colspan="4"/>

string属性定义了它的标签,colspan属性定义了他的水平大小(列的个数)。

Notebook

<notebook>: 用notebooks你可以分配视图字段在不同的标签上(每个由page tag定义)。你可以使用tabpos属性来设置tab:up,down,left,right。

Example:
<notebook colspan="4">....</notebook>

Group

<group>: 对几个列进行分组。

  • colspan: 被使用的列数
  • rowspan: 被使用的行数
  • expand: 是否扩展该分组
  • col:被提供的列数 (给他的下级)
  • string: (可选) 如果设置了,将在字段组周围绘制一个框架, 包括这个string作为标签. 否则,这个框架是不可见的.
Example:
<group col="3" colspan="2">
    <field name="invoiced" select="2"/>
    <button colspan="1" name="make_invoice" states="confirmed" string="Make Invoice"
        type="object"/>
</group>

Page

为视图定义新的notebook

Example:
<page string="Order Line"> ... </page>:
  • string: 定义page的名称

数据元素

Field

“field” tag的属性

  • select="1": 标记这个是search 视图的搜索条件之一 。
    数值1 意思是这个字段被被包括在基本搜索里 数值2 意思是这个字段在高级搜索中.
  • colspan="4": 字段被扩展开的列数.
  • readonly="1": 设置位置 只读
  • required="1": 该字段被标记为 必须. 如果字段被标记为必须,用户必须填写它,如果字段不填,系统不会保存资源。这个属性将取代 对象中的定义的required 字段值.
  • nolabel="1": 隐藏字段的便签(但是这个字段在 search 视图不会被隐藏).
  • invisible="True": 隐藏标签和字段.
  • password="True": 用 星号替换字段值, “*”.
  • string="": 改变字段的标签. 注意,这个标签也会用在search视图: 看上面的 select 属性).
  • domain: 约束条件.
    • Example: domain=”[(‘partner_id’,’=’,partner_id)]”
  • widget: 可改变 widget.
    • Example: widget=”one2many_list”
      • one2one_list
      • one2many_list
      • many2one_list
      • many2many
      • url
      • email
      • image
      • float_time
      • reference
  • mode: 视图切换时的顺序.
    • Example: mode=”tree,graph”
  • on_change: 定义一个 函数,当字段内容被改变时调用.
    • Example: on_change=”onchange_partner(type,partner_id)”
    • 要更详细的内容,查看 on change event .
  • attrs: 允许定义一个字段的取决于同一窗口其它字段 的属性 . (也可用在 page, group, button and notebook 标签中o)
    • 格式: “{‘attribute’:[(‘field_name’,’operator’,’value’),(‘field_name’,’operator’,’value’)],’attribute2’:[(‘field_name’,’operator’,’value’),]}”
    • 这里的 attribute 是 readonly, invisible, required
    • 默认值: {}.
    • 例子在: (in product.product)
<field digits="(14, 3)" name="volume" attrs="{'readonly':[('type','=','service')]}"/>
  • eval: evaluate the attribute content as if it was Python code (see below for example)

  • default_focus: set to 1 to put the focus (cursor position) on this field when the form is first opened. There can only be one field within a view having this attribute set to 1 (new as of 5.2)

    <field name="name" default_focus=”1”/>
    

Example

这有销售订单对象视图的源代码。这是相同对象作为对象在截图中的显示。

Example:
<?xml version="1.0"?>
<openerp>
    <data>
    <record id="view_partner_form" model="ir.ui.view">
            <field name="name">res.partner.form</field>
            <field name="model">res.partner</field>
            <field name="type">form</field>
            <field name="arch" type="xml">
            <form string="Partners">
                <group colspan="4" col="6">
                    <field name="name" select="1"/>
                    <field name="ref" select="1"/>
                    <field name="customer" select="1"/>
                    <field domain="[('domain', '=', 'partner')]" name="title"/>
                    <field name="lang" select="2"/>
                    <field name="supplier" select="2"/>
                </group>
                <notebook colspan="4">
                    <page string="General">
                        <field colspan="4" mode="form,tree" name="address"
                         nolabel="1" select="1">
                            <form string="Partner Contacts">
                                <field name="name" select="2"/>
                                <field domain="[('domain', '=', 'contact')]" name="title"/>
                                <field name="function"/>
                                <field name="type" select="2"/>
                                <field name="street" select="2"/>
                                <field name="street2"/>
                                <newline/>
                                <field name="zip" select="2"/>
                                <field name="city" select="2"/>
                                <newline/>
                                <field completion="1" name="country_id" select="2"/>
                                <field name="state_id" select="2"/>
                                <newline/>
                                <field name="phone"/>
                                <field name="fax"/>
                                <newline/>
                                <field name="mobile"/>
                                <field name="email" select="2" widget="email"/>
                            </form>
                            <tree string="Partner Contacts">
                                <field name="name"/>
                                <field name="zip"/>
                                <field name="city"/>
                                <field name="country_id"/>
                                <field name="phone"/>
                                <field name="email"/>
                            </tree>
                        </field>
                        <separator colspan="4" string="Categories"/>
                        <field colspan="4" name="category_id" nolabel="1" select="2"/>
                    </page>
                    <page string="Sales &amp; Purchases">
                        <separator string="General Information" colspan="4"/>
                        <field name="user_id" select="2"/>
                        <field name="active" select="2"/>
                        <field name="website" widget="url"/>
                        <field name="date" select="2"/>
                        <field name="parent_id"/>
                        <newline/>
                    </page>
                    <page string="History">
                        <field colspan="4" name="events" nolabel="1" widget="one2many_list"/>
                    </page>
                    <page string="Notes">
                        <field colspan="4" name="comment" nolabel="1"/>
                    </page>
                </notebook>
            </form>
            </field>
        </record>
    <menuitem
            action="action_partner_form"
            id="menu_partner_form"
            parent="base.menu_base_partner"
            sequence="2"/>
    </data>
 </openerp>
The eval attribute

eval属性评估它的内容像Python代码似地。这就允许你定义不是字符串的值。

一般情况下,内容中<field>标签一直作为字符串来计算。

Example 1:
<field name="value">2.3</field>

2.3不是float 2.3而是字符串2.3

Example 2:
<field name="value">False</field>

False不是布尔值False,而是字符串’False’。 This is especially tricky because Python’s conversion rules consider any non-empty string to be True, so the above code will end up storing the opposite of what is desired.

如果你想要计算float,boolean或是其他类型,除了string,可以使用eval属性:

<field name="value" eval="2.3" />
<field name="value" eval="False" />

Button

加button到当前视图中。允许用户在当前记录上执行各种动作。

点击button按钮后,记录会重新装载。

Buttons有以下的属性:

@type
定义button按钮激活后action执行类型。
workflow (default)
button会在当前model上发送workflow signal,使用button的name作为workflow signal name并且提供记录id作为参数(in a list)。
workflow signal会返回一个动作描述符,已执行的。否则会返回False。
object
button会在当前model上执行@name的方法,提供一个记录id作为参数(in a list)。该调用会返回一个动作描述符来执行。
action
button会触发action(ir.actions.actions)来执行。这个动作的id是button的@name。
From there, follows the normal action-execution workflow. One extra action type is to just close the window.
return {'type': 'ir.actions.act_window_close'}
@special
当前仅有一个可能值:cancel,popup在没有RPC调用或是action执行时就会关闭。

Note

Only meaningful within a popup-type window (e.g. a wizard). Otherwise, is a noop.

Warning

@special and @type are incompatible.

@name
button的标识符,用于指出调用哪个方法,发送哪个signal,执行哪个动作。
@confirm
当执行button的任务前,确认对话框会显示。当确认取消后,button的任务不会执行。
@string
button上会显示的标签。 [1].
@icon
显示button图表,如果没有这个button就是text-only [2].
@states, @attrs, @invisible
OpenERP这些视图属性的标准含义。
@default_focus
如果设置为确认值(1)时,当点击RETURN时就会自动搜索按钮。
client端会忽视这个属性。

New in version 6.0.

Example:
<button name="order_confirm" states="draft" string="Confirm Order" icon="gtk-execute"/>
<button name="_action_open_window" string="Open Margins" type="object" default_focus=”1”/>

Label

用label来加个标题。

Example:
<label string="Test"/>

New Line

如果视图的所有列不能全部放进一行是强制换行。

Example:
<newline/>
[1]via exec_workflow on the object rpc endpoint
[2]in form view, in list view buttons have no label
[3]behavior in list view is undefined, as list view buttons don’t have labels.

Inheritance in Views

当你要在一些自定义或是特定的模块上创建和继承对象时,在已经存在的视图上通过继承来添加/修改/删除一些字段相比于替换更好些。

Example:
<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="relation_ids" colspan="4" nolabel="1"/>
            </page>
        </notebook>
    </field>
</record>

这是要在base模块上给res.partner.form的notebook里面加一个page。

继承engine会分析已存在的视图并且搜索的根节点。

<field name="arch" type="xml">

它会添加或是修改这个标签的内容。如果这个标签有很多属性,它会查找父类视图来匹配这些属性。

在位置属性上你可以使用以下的值:

  • inside (default): your values will be appended inside the tag
  • after: add the content after the tag
  • before: add the content before the tag
  • replace: replace the content of the tag.

Replacing Content

<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="relation_ids" colspan="4" nolabel="1"/>
        </page>
    </field>
</record>

可用relation_ids字段来替换notebook的额外信息标签的内容。

父类和子类的视图可像其他视图一样通过—update=all来进行更新。

Deleting Content

想要删除表单视图中的一个字段,可使用position=”replace”属性。

<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>

Inserting Content

想要加一个字段到form中在特定标签前的话,使用position=’before’属性。

<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>

在lang字段前加relation_ids字段。

想要加一个字段到form中在指定标签后的话,使用position=’before’属性。

<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>

在lang字段后加relation_ids字段。

Multiple Changes

想要在多个位置进行更改,在数据元素中包裹多个字段。

<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">
        <data>
            <field name="lang" position="replace"/>
            <field name="website" position="after">
                <field name="lang"/>
            </field>
        </data>
    </field>
</record>

在平常位置删除lang字段,在website后显示它。

XPath Element

有时视图因为太复杂了而不能让你简单的通过name找到字段。例如,字段显示在两个地方。在这种情况下,你可以使用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="//field[@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>

在表单视图和列表视图中添加age字段在email字段后。

Replacing Attributes

The attributes position lets you change an element’s attributes without completely replacing it and its children. A common example is changing the colours in a tree view.

<record id="mrp_production_tree_view" model="ir.ui.view">
  <field name="name">mrp.production.mycompany.tree.view</field>
  <field name="model">mrp.production</field>
  <field name="type">tree</field>
  <field name="inherit_id" ref="mrp.mrp_production_tree_view"/>
  <field name="arch" type="xml">
    <xpath expr="//tree" position="attributes">
      <attribute name="colors">blue:state=='draft'</attribute>
    </xpath>
  </field>
</record>

指定你要使用的视图

在几种情况下你相比于默认的视图更想用指定的视图:

  • 如果一个对象有好几种表单或是列表视图。
  • 如果你想要通过使用关系字段(如one2many)来更改表单或是列表视图。

使用优先级字段(priority field)

这个字段在视图定义中是可用的,默认为16。在默认情况下,OpenERP用最高优先级(更小的值)的视图来显示model。比如,想象我们的一个model有两个视图。model client有两个字段:firstname和lastname。我们将会定义两个视图,一个用于首先显示firstname,另一个用于首先显示lastname。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!--
    Here is the first view for the model 'client'.
    We don't specify a priority field, which means
    by default 16.
    这是模型‘client'的第一个视图。
    我们不指定priority字段,意味着是默认值16
-->
<record model="ir.ui.view" id="client_form_view_1">
    <field name="name">client.form.view1</field>
    <field name="model">client</field>
    <field name="type">form</fiel>
    <field name="arch" type="xml">
        <field name="firstname"/>
        <field name="lastname"/>
    </field>
</record>

<!--
    A second view, which show fields in an other order.
    We specify a priority of 15.
    在 用另外的顺序显示字段的第二个视图,我们指定了priority为15.
-->
<record model="ir.ui.view" id="client_form_view_2">
    <field name="name">client.form.view2</field>
    <field name="model">client</field>
    <field name="priority" eval="15"/>
    <field name="type">form</fiel>
    <field name="arch" type="xml">
        <field name="lastname"/>
        <field name="firstname"/>
    </field>
</record>

现在,OpenERP每次为对象client显示表单视图,它都有两个视图选择。它一直选择的是第二个,因为这个有高优先级。除非你告诉它选择第一个。

Specify per-action view

为了说明这一点,我们将会创建2个菜单来为client对象显示表单视图。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!--
    This action open the default view (in our case,
    the view with the highest priority, the second one)
    此actionb打开了默认视图(在我们的例子中,这个视
            图有最优先级 ,第二个方法  -->
<record
    model="ir.actions.act_window"
    id="client_form_action">
    <field name="name">client.form.action</field>
    <field name="res_model">client</field>
    <field name="view_type">form</field>
    <field name="view_mode">form</field>
</record>

<!--
    This action open the view we specify.
    这个 action 打开我们指定的视图
-->
<record
    model="ir.actions.act_window"
    id="client_form_action1">
    <field name="name">client.form.action1</field>
    <field name="res_model">client</field>
    <field name="view_type">form</field>
    <field name="view_mode">form</field>
    <field name="view_id" ref="client_form_view_1"/>
</record>

<menuitem id="menu_id" name="Client main menu"/>
<menuitem
    id="menu_id_1"
    name="Here we don't specify the view"
    action="client_form_action" parent="menu_id"/>
<menuitem
    id="menu_id_1"
    name="Here we specify the view"
    action="client_form_action1" parent="menu_id"/>

你可以看到第19行,我们特定了一个视图。这意味着当我们打开第二个菜单时,OpenERP将会使用视图client_form_view_1,而不管它的优先级。

Note

记住,如果在 ref 属性中涉及在另外模块定义的一个视图,要使用模块名 (module.view_id) .

事件

On Change 事件

当一个字段的内容发生改变时,on_change属性定义个方法就会被调用。

这个方法至少有几个参数:cr,uid,ids,这是三个传统的参数并且也在上下文字典中。你需要给方法添加参数。他们必须符合在视图中定义的其他字段,并且必须在XML中以以下的方式定义::

<field
    name="name_of_field"
    on_change="name_of_method(other_field_1, ..., other_field_n)"/>

下面的是来自销售订单视图中的例子。

你可以使用‘context’关键字来访问上下文中的数据,这个上下文可以被用作函数中的参数::

<field name="shop_id" on_change="onchange_shop_id(shop_id)"/>
def onchange_shop_id(self, cr, uid, ids, shop_id):

    v={}
    if shop_id:

        shop=self.pool.get('sale.shop').browse(cr,uid,shop_id)
        v['project_id']=shop.project_id.id
        if shop.pricelist_id.id:

            v['pricelist_id']=shop.pricelist_id.id

        v['payment_default_id']=shop.payment_default_id.id

    return {'value':v}

当编辑shop_id表单字段时,sale_order对象的onchange_shop_id方法会被调用,并且返回一个字典,其中‘value’关键字包含在’project_id’, ‘pricelist_id’, ‘payment_default_id’字段中新值来使用的字典。

我们注意到除了字段值,更改更多的东西是可能的。例如,可以更改字段值和其他字段的domain,这个更改通过表单的返回值:return {‘domain’: d, ‘value’: value}

returns:一个字典有以下关键字任意的混合:
domain {field: domain} 的一个映射
这个返回的domains将被设置在该字段上,以替换默认的一个。
value {field: value}} 的映射,这个值将会在相对应的字段上设置,可能触发新的onchanges或是attrs changes。
warning 有关键字``title`` 和 ``message``(两个是必须的)的字典。指出显示给用户的错误信息。