高級視圖
樹視圖
樹視圖可以采用輔助屬性來進一步自定義其行為:
decoration-{$name}
允許根據(jù)對應(yīng)記錄屬性修改行的文本風格躬翁。對于每個記錄倔韭,將使用記錄的屬性作為上下文來計算表達式拱层,如果值為true
,則將相應(yīng)的樣式應(yīng)用于行成玫。其他上下文值為uid
(當前用戶的標識)和current_date
(yyyy-MM-dd
格式的當前日期字符串)骇两。{$name}
可以是bf(font-weight:bold)
速种、it(font-style:italic)
或任何bootstrap上下文顏色(danger,info,muted,primary,success,warning
)
<tree string="Idea Categories" decoration-info="state=='draft'"
decoration-danger="state=='trashed'">
<field name="name"/>
<field name="state"/>
</tree>
editable
top
和bottom
使樹視圖可直接編輯(而不需要通過表單視圖),其值就是新行出現(xiàn)的位置低千。
練習列表著色
編輯授課的樹視圖配阵,使得持續(xù)時間少于5天的授課以藍色顯示,持續(xù)時間超過15天的授課以紅色顯示示血。編輯授課的樹視圖:
openacademy/views/openacademy.xml
<field name="name">session.tree</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<tree string="Session Tree" decoration-info="duration<5" decoration-danger="duration>15">
<field name="name"/>
<field name="course_id"/>
<field name="duration" invisible="1"/>
<field name="taken_seats" widget="progressbar"/>
</tree>
</field>
日歷
將記錄顯示為日歷活動棋傍,通過將根元素設(shè)置為<calendar>
,主要的屬性有:
color
字段的名稱通過顏色來區(qū)分难审。顏色會自動分配給事件瘫拣,但相同顏色定義的事件(@color
屬性有相同值的記錄)將被使用相同的顏色。
date_start
記錄中用于保存事件開始日期/時間的字段告喊。
date_stop
(可選)
記錄中用于保存時間結(jié)束日期/時間的字段麸拄。
為每個日歷事件定義標簽的字段
<calendar string="Ideas" date_start="invent_date" color="inventor_id">
<field name="name"/>
</calendar>
練習日歷視圖
給授課模型添加一個日歷視圖派昧,使用戶可以查看與開放學院相關(guān)聯(lián)的事件。
- 添加一個計算字段
end_date
拢切,通過start_date
和duration
計算獲得蒂萎。 - 反函數(shù)使字段可寫,并允許在日歷視圖中移動授課(通過拖放操作)
- 向授課模型添加日歷視圖
- 添加日歷視圖到授課模型的動作中
openacademy/models.py
# -*- coding: utf-8 -*-
from datetime import timedelta
from odoo import models, fields, api, exceptions
class Course(models.Model):
attendee_ids = fields.Many2many('res.partner', string="Attendees")
taken_seats = fields.Float(string="Taken seats", compute='_taken_seats')
end_date = fields.Date(string="End Date", store=True,
compute='_get_end_date', inverse='_set_end_date')
@api.depends('seats', 'attendee_ids')
def _taken_seats(self):
},
}
@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
start = fields.Datetime.from_string(r.start_date)
duration = timedelta(days=r.duration, seconds=-1)
r.end_date = start + 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
start_date = fields.Datetime.from_string(r.start_date)
end_date = fields.Datetime.from_string(r.end_date)
r.duration = (end_date - start_date).days + 1
@api.constrains('instructor_id', 'attendee_ids')
def _check_instructor_not_in_attendees(self):
for r in self:
openacademy/views/openacademy.xml
</field>
</record>
<!-- 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_type">form</field>
<field name="view_mode">tree,form,calendar</field>
</record>
<menuitem id="session_menu" name="Sessions"
搜索視圖
搜索視圖的<field>
元素可以使用@filter_domain
覆蓋為在給定字段上搜索而生成的域淮椰。在給定的域中五慈,self
表示用戶輸入的值。在下面的示例中实苞,它用于搜索兩個字段name
和description
豺撑。搜索視圖還可以包含<filter>
元素,這些元素用作預(yù)定義搜索的切換黔牵。過濾器必須具有以下屬性之一:
domain
給搜索指定domain表達式
context
給搜索指定上下文聪轿;使用group_by
對結(jié)果進行分組。
<search string="Ideas">
<field name="name"/>
<field name="description" string="Name and description"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
<field name="inventor_id"/>
<field name="country_id" widget="selection"/>
<filter name="my_ideas" string="My Ideas"
domain="[('inventor_id', '=', uid)]"/>
<group string="Group By">
<filter name="group_by_inventor" string="Inventor"
context="{'group_by': 'inventor_id'}"/>
</group>
</search>
對于非默認的搜索視圖猾浦,使用search_view_id
字段陆错。而通過context
字段為搜索字段設(shè)置默認值:search_default_field_name
表單的上下文關(guān)鍵字將初始化field_name的值。搜索過濾器必須有@name
選項金赦,并且其值是布爾類型的(只能在默認情況可用)
練習搜索視圖
- 在課程搜索視圖中添加按鈕音瓷,用以篩選當前用戶負責的課程,并且作為默認選擇夹抗。
- 再添加一個分組按鈕绳慎,用于對當前用戶負責的課程進行分組。
openacademy/views/openacademy.xml
<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="res_model">openacademy.course</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context" eval="{'search_default_my_courses': 1}"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first course
</p>
甘特圖
水平條狀的甘特圖通常用于顯示項目計劃和進度漠烧,根元素是<gantt>
杏愤。
<gantt string="Ideas"
date_start="invent_date"
date_stop="date_finished"
progress="progress"
default_group_by="inventor_id" />
練習甘特圖
添加甘特圖使用戶可以查看授課的日程排期,授課將按講師分組已脓。
- 創(chuàng)建一個計算字段珊楼,表示以小時計算的授課持續(xù)時間
- 添加甘特圖,并且將甘特圖添加到授課模型的action上度液。
openacademy/models.py
end_date = fields.Date(string="End Date", store=True,
compute='_get_end_date', inverse='_set_end_date')
hours = fields.Float(string="Duration in hours",
compute='_get_hours', inverse='_set_hours')
@api.depends('seats', 'attendee_ids')
def _taken_seats(self):
for r in self:
end_date = fields.Datetime.from_string(r.end_date)
r.duration = (end_date - start_date).days + 1
@api.depends('duration')
def _get_hours(self):
for r in self:
r.hours = r.duration * 24
def _set_hours(self):
for r in self:
r.duration = r.hours / 24
@api.constrains('instructor_id', 'attendee_ids')
def _check_instructor_not_in_attendees(self):
for r in self:
openacademy/views/openacademy.xml
</field>
</record>
<record model="ir.ui.view" id="session_gantt_view">
<field name="name">session.gantt</field>
<field name="model">openacademy.session</field>
<field name="arch" type="xml">
<gantt string="Session Gantt" color="course_id"
date_start="start_date" date_delay="hours"
default_group_by='instructor_id'>
<field name="name"/>
</gantt>
</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_type">form</field>
<field name="view_mode">tree,form,calendar,gantt</field>
</record>
<menuitem id="session_menu" name="Sessions"
圖形視圖
圖形視圖用來表示對模型的概述和分析厕宗,根元素是<graph>
。
注意
多維表的核心視圖(根元素<pivot>
)允許選擇文件管理器以獲得正確的圖形數(shù)據(jù)庫堕担,然后再轉(zhuǎn)到更多的圖形視圖已慢。核心視圖與圖形視圖共享相同的內(nèi)容定義。
聚合視圖有4種顯示模式照宝,通過@type
屬性定義蛇受。
Bar(默認值)
條形圖,第一個維度用于在水平軸上定義組厕鹃,其它維度定義每個組的聚合條兢仰。默認情況下乍丈,條是并排的,也可以通過<graph>
的@stacked="True"
來讓條堆疊把将。
Line
2維折線圖
Pie
2維餅圖
圖形視圖包含的<field>
元素有@type
屬性定義值:
row(默認值)
該字段是聚合的
measure
該字段是分組后聚合的
<graph string="Total idea score by Inventor">
<field name="inventor_id"/>
<field name="score" type="measure"/>
</graph>
警告
圖形視圖只能對數(shù)據(jù)庫字段進行聚合轻专,不能對不存儲在數(shù)據(jù)庫的計算字段進行聚合。
練習圖形視圖
在授課對象中添加圖形視圖察蹲,為每個課程在條形視圖下顯示出席人數(shù)请垛。
- 添加字段將出席人數(shù)這計算字段存儲在數(shù)據(jù)庫
- 添加相關(guān)圖形視圖
openacademy/models.py
hours = fields.Float(string="Duration in hours",
compute='_get_hours', inverse='_set_hours')
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:
for r in self:
r.duration = r.hours / 24
@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/views/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_type">form</field>
<field name="view_mode">tree,form,calendar,gantt,graph</field>
</record>
<menuitem id="session_menu" name="Sessions"
看板視圖
看板視圖用于任務(wù)組織、生產(chǎn)進度等洽议,根元素是<kanban>
宗收。看板視圖顯示一組可按列分組的卡片亚兄。每個卡片表示一個記錄混稽,每列都顯示聚合字段的值。例如項目任務(wù)可以按階段(每列是一個階段)分組或者按負責人(每列是一個用戶)分組审胚⌒傺看板視圖將每個卡的結(jié)構(gòu)定義為表單元素(包括基本HTML)和QWeb的混合。
練習看板視圖
添加顯示按課程分組的授課看板視圖(列是課程)
- 授課模型中添加整型字段
color
- 添加看板視圖并更新action
openacademy/models.py
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),
openacademy/views/openacademy.xml
</record>
<record model="ir.ui.view" id="view_openacad_session_kanban">
<field name="name">openacad.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"/>
<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_type">form</field>
<field name="view_mode">tree,form,calendar,gantt,graph,kanban</field>
</record>
<menuitem id="session_menu" name="Sessions"
parent="openacademy_menu"