一、高级视图
1、树视图
树视图可以采用补充属性来进一步自定义其行为:
decoration-{$name}
允许根据相应记录的属性更改行文本的样式。
值是Python表达式。对于每条记录,将使用记录的属性作为上下文值评估表达式,如果为true
,则将相应样式应用于行。其他上下文值是 uid
(当前用户的ID)和current_date
(当前日期,形式为字符串yyyy-MM-dd
)。
{$name}
可以是bf
(font-weight: bold
), (it
),font-style: italic
或任何枚举上下文颜色(danger
, info
,muted
,primary
,success
或warning
)。
列表着色
修改session树视图,使持续时间少于5天的会话显示为蓝色,而持续时间超过15天的会话显示为红色。
修改views/openacademy.xml中session树视图如下
<field name="name">session.tree</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<!--decoration filter -->
<tree string="Session Tree" decoration-info="duration<5" decoration-danger="duration>15">
<field name="name"/>
<field name="course_id"/>
<!--add duration field -->
<field name="duration" invisible="1"/>
<field name="taken_seats" widget="progressbar"/>
</tree>
</field>
运行效果
2、行事历
将记录显示为日历事件。它们的根元素是<calendar>
,最常见的属性是:
color
用于颜色分割的字段名称。颜色将自动分配给事件,但是相同颜色段(其@color
字段具有相同值的记录)中的事件将被赋予相同的颜色。
date_start
记录中包含事件开始日期/时间的字段
date_stop
(可选的)
记录的字段,其中包含事件的结束日期/时间
string
记录的字段以定义每个日历事件的标签
修改models\models.py文件中session对象,增加一个计划属性end_date,其值由start_date和duration计算得出。
# -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import models, fields, api, exceptions
class Session(models.Model):
#...
taken_seats = fields.Float(string="Taken seats", compute='_taken_seats')
#add end_date
end_date = fields.Date(string="End Date", store=True, compute='_get_end_date', inverse='_set_end_date')
#...
#add compute function
@api.depends('start_date', 'duration')
def _get_end_date(self):
for r in self:
if not (r.start_date and r.duration):
r.end_date = r.start_date
continue
# Add duration to start_date, but: Monday + 5 days = Saturday, so
# subtract one second to get on Friday instead
duration = timedelta(days=r.duration, seconds=-1)
r.end_date = r.start_date + duration
def _set_end_date(self):
for r in self:
if not (r.start_date and r.end_date):
continue
# Compute the difference between dates, but: Friday - Monday = 4 days,
# so add one day to get 5 days instead
r.duration = (r.end_date - r.start_date).days + 1
修改views/openacademy.xml,增加行事历视图
<!--定义 calendar view -->
<record model="ir.ui.view" id="session_calendar_view">
<field name="name">session.calendar</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<calendar string="Session Calendar" date_start="start_date" date_stop="end_date" color="instructor_id">
<field name="name"/>
</calendar>
</field>
</record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
<!--增加行事历图 -->
<field name="view_mode">tree,form,calendar</field>
</record>
<menuitem id="session_menu" name="Sessions"
运行效果
3、搜索视图
搜索视图<field>
元素可以具有@filter_domain
,以覆盖为在给定字段上进行搜索而生成的域。在给定的域中, self
代表用户输入的值。在下面的例子中,它是用来在两个字段进行搜索name
和description
。
搜索视图还可以包含<filter>
元素,这些元素充当预定义搜索的切换。筛选器必须具有以下属性之一:
domain
将给定的域添加到当前搜索中
context
在当前搜索中添加一些上下文;使用键group_by
将结果按给定的字段名称分组
修改views/openacademy.xml中course视图
- 添加一个按钮以过滤课程搜索视图中当前用户负责的课程。使其默认为选中状态。
- 添加按钮以按负责任的用户对课程进行分组
<search>
<field name="name"/>
<field name="description"/>
<!--增加搜索、分组按钮-->
<filter name="my_courses" string="My Courses"
domain="[('responsible_id', '=', uid)]"/>
<group string="Group By">
<filter name="by_responsible" string="Responsible"
context="{'group_by': 'responsible_id'}"/>
</group>
</search>
</field>
</record>
<!--
...
-->
<field name="name">Courses</field>
<field name="res_model">openacademy.course</field>
<field name="view_mode">tree,form</field>
<!--courses by responsible user-->
<field name="context" eval="{'search_default_my_courses': 1}"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">Create the first course
</p>
运行效果
4、图表视图
图形视图允许对模型进行汇总概述和分析,其根元素为<graph>
。
图表视图具有4种显示模式,使用@type
属性可以选择默认模式 。
Bar(默认)
在条形图中,第一维用于定义水平轴上的组,其他维用于定义每个组内的聚合条。
默认情况下,条形是并排放置的,可以通过 @stacked="True"
在<graph>
Line
二维折线图
Pie
二维派
图形视图包含<field>
带有强制@type
属性的值:
row
(默认)
该字段应默认汇总
measure
该字段应汇总而不是分组
修改models\models.py,在“Session”对象中添加一个“图形”视图,该视图以条形图的形式显示每个课程的参加人数。
- 将与会者人数attendees_count添加为存储的计算字段
- 然后添加相关视图
end_date = fields.Date(string="End Date", store=True,
compute='_get_end_date', inverse='_set_end_date')
#添加与会人数计算属性
attendees_count = fields.Integer(
string="Attendees count", compute='_get_attendees_count', store=True)
@api.depends('seats', 'attendee_ids')
def _taken_seats(self):
for r in self:
# so add one day to get 5 days instead
r.duration = (r.end_date - r.start_date).days + 1
#添加计算函数
@api.depends('attendee_ids')
def _get_attendees_count(self):
for r in self:
r.attendees_count = len(r.attendee_ids)
@api.constrains('instructor_id', 'attendee_ids')
def _check_instructor_not_in_attendees(self):
for r in self:
在openacademy.xml添加图表视图
</field>
</record>
<!--添加图表视图-->
<record model="ir.ui.view" id="openacademy_session_graph_view">
<field name="name">openacademy.session.graph</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<graph string="Participations by Courses">
<field name="course_id"/>
<field name="attendees_count" type="measure"/>
</graph>
</field>
</record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
<!--添加图表-->
<field name="view_mode">tree,form,calendar,graph</field>
</record>
<menuitem id="session_menu" name="Sessions"
运行效果
5、看板
用于组织任务,生产过程等……其根元素是 <kanban>
。
看板视图显示一组可能按列分组的卡片。每张卡代表一条记录,每列代表一个聚合字段的值。
例如,项目任务可以按阶段(每个列是一个阶段)或负责任的方式(每个列是一个用户)进行组织,等等。
添加一个看板视图,该视图显示按课程分组的会话(因此,列就是课程)。
- 将一个整数
color
字段添加到会话模型 - 添加看板视图并更新操作
修改models\models.py,为session对象增加color属性
duration = fields.Float(digits=(6, 2), help="Duration in days")
seats = fields.Integer(string="Number of seats")
active = fields.Boolean(default=True)
# 增加
color = fields.Integer()
instructor_id = fields.Many2one('res.partner', string="Instructor",
domain=['|', ('instructor', '=', True),
修改views\openacademy.xml增加kanban视图
</field>
</record>
<!--看板视图-->
<record model="ir.ui.view" id="view_openacad_session_kanban">
<field name="name">openacademy.session.kanban</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<kanban default_group_by="course_id">
<field name="color"/>
<templates>
<t t-name="kanban-box">
<div
t-attf-class="oe_kanban_color_{{kanban_getcolor(record.color.raw_value)}}
oe_kanban_global_click_edit oe_semantic_html_override
oe_kanban_card {{record.group_fancy==1 ? 'oe_kanban_card_fancy' : ''}}">
<div class="oe_dropdown_kanban">
<!-- dropdown menu -->
<div class="oe_dropdown_toggle">
<i class="fa fa-bars fa-lg" title="Manage" aria-label="Manage"/>
<ul class="oe_dropdown_menu">
<li>
<a type="delete">Delete</a>
</li>
<li>
<ul class="oe_kanban_colorpicker"
data-field="color"/>
</li>
</ul>
</div>
<div class="oe_clear"></div>
</div>
<div t-attf-class="oe_kanban_content">
<!-- title -->
Session name:
<field name="name"/>
<br/>
Start date:
<field name="start_date"/>
<br/>
duration:
<field name="duration"/>
</div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessions</field>
<field name="res_model">openacademy.session</field>
<!-- 增加看板 -->
<field name="view_mode">tree,form,calendar,graph,kanban</field>
</record>
运行效果
参考文档
https://www.odoo.com/documentation/13.0/howtos/backend.html#build-an-odoo-module