View Records¶
Views are what define how records should be displayed to end-users. They are specified in XML which means that they can be edited independently from the models that they represent. They are flexible and allow a high level of customization of the screens that they control. There exist various types of views. Each of them represents a mode of visualization: form, list, kanban, etc.
Generic structure¶
Basic views generally share the common structure defined below. Placeholders are denoted in all caps.
<record id="ADDON.MODEL_view_TYPE" model="ir.ui.view">
<field name="name">NAME</field>
<field name="model">MODEL</field>
<!--
<field name="groups_id" eval="GROUPS"/>
<field name="priority">PRIORITY</field>
-->
<!--
<field name="inherit_id" ref="REFERENCE"/>
<field name="mode">PRIMARY</field>
-->
<field name="arch" type="xml">
<VIEW_TYPE>
<views/>
</VIEW_TYPE>
</field>
</record>
View types¶
Form -> display and edit the data from a single record
List -> view and edit multiple records
Search -> apply filters and perform searches (the result are displayed in the current view list, kanban…)
Kanban -> displays records as “cards” configurable as a small template
Qweb -> templating of reporting, website…
Graph -> visualize aggregations over a number of records or record groups
Pivot -> display aggregations as a pivot table
Calendar -> display records as events in a daily, weekly, monthly or yearly calendar
Fields¶
View objects expose a number of fields. They are optional unless specified otherwise.
- name
-
Only useful as a mnemonic/description of the view when looking for one in a list of some sort. Most Odoo view names start with the name of the addon and end with the type of view being discussed.
- model
Char
(mandatory)The model linked to the view, if applicable.
- arch
-
The description of the view layout depending on view type
- groups_id
Many2many
->Groups
The groups allowed to use/access the current view.
If the view extends an existing view, the extension will only be applied for a given user if the user has access to the provided
groups_id
.- priority
-
When a view is requested by
model
andtype
, the view matching the model and the type, with the lowest priority will be returned (it is the default view).It also defines the order of views application during view inheritance. When a view is requested by
id
, if its mode is notprimary
its closest parent withmode
primary
is matched. - inherit_id
-
Reference to the parent view on which the inheritance will be applied. It value is uset by default. Specify the parent using the
ref
attribute asref="ADDON.MODEL_parent_view_TYPE"
. The addon name (separate by dot) is not necessary if the inheritance is done on a record of the same module.See inheritance information
- mode
Selection
:extension
/primary
Only applies if this view inherits from an other one (inherit_id is not False/Null).
- extension (default)
if this view is requested the closest primary view is looked up (via inherit_id), then all views inheriting from it with this view’s model are applied
- primary
the closest primary view is fully resolved (even if it uses a different model than this one), then this view’s inheritance specs (<xpath/>) are applied, and the result is used as if it were this view’s actual arch.
An example of where you would want to override
mode
while usinginherit_id
is delegation inheritance. In that case your derived model will be separate from its parent and views matching with one won’t match with the other. Suppose you inherit from a view associated with the parent model and want to customize the derived view to show data from the derived model. Themode
of the derived view needs to be set toprimary
, because it’s the base (and maybe only) view for that derived model. Otherwise the view matching rules won’t apply.See inheritance information
Note
The current context and user access rights may also impact the view abilities.
Inheritance¶
Inheritance allows you to customize delivered views. This makes it possible, for example, to add content according to the modules installed, or to deliver different displays according to the action.
Inherit views generally share the common structure defined below. Placeholders are denoted in all caps. This synthetic view will update a node targeted by an xpath, and an other targeted by his name and attributes.
The two following view fields inherit_id
and
mode
are used to specify inherited views.
<record id="ADDON.MODEL_view_TYPE" model="ir.ui.view">
<field name="model">MODEL</field>
<field name="inherit_id" ref="VIEW_REFERENCE"/>
<!--
<field name="mode">PRIMARY</field>
-->
<field name="arch" type="xml">
<xpath expr="XPATH" position="inside">
CONTENT
</xpath>
<NODE ATTRIBUTES="VALUES" position="replace">
<CONTENT/>
</NODE>
</field>
</record>
View resolution¶
Resolution generates the final arch
for a requested/matched primary
view:
if the view has a parent, the parent is fully resolved then the current view’s inheritance specs are applied
if the view has no parent, its
arch
is used as-isthe current view’s children with mode
extension
are looked up and their inheritance specs are applied depth-first (a child view is applied, then its children, then its siblings)
The inheritance is applied according to inherit_id
. If several view
record inherit the same view, the order is determined by the priority
.
The result of applying children views yields the final arch
Inheritance specs¶
Inheritance specs are comprised of an element locator, to match the inherited element in the parent view, and children element that will be used to modify the inherited element.
There are three types of element locators for matching a target element:
An
xpath
element with anexpr
attribute.expr
is an XPath expression1 applied to the currentarch
, the first node it finds is the matcha
field
element with aname
attribute, matches the firstfield
with the samename
. All other attributes are ignored during matchingany other element: the first element with the same name and identical attributes (ignoring
position
andversion
attributes) is matched
<xpath expr="page[@name='pg']/group[@name='gp']/field" position="inside">
<field name="description"/>
</xpath>
<div name="name" position="replace">
<field name="name2"/>
</div>
The view’s specs are applied sequentially.
- 1
an extension function is added for simpler matching in QWeb views:
hasclass(*classes)
matches if the context node has all the specified classes
Inheritance position¶
The inheritance spec may have an optional position
attribute specifying
how the matched node should be altered. By default the value is inside
.
- inside
the content of the inheritance spec is appended to the matched node
<notebook position="inside"> <page string="New feature"> ... </page> </notebook>
- after
the content of the inheritance spec is added to the matched node’s parent, after the matched node
<xpath expr="//field[@name='x_field']" position="after"> <field name="x_other_field"/> </xpath>
- before
the content of the inheritance spec is added to the matched node’s parent, before the matched node
<field name=x_field" position="before"> <field name="x_other_field"/> </field>
- replace
the content of the inheritance spec replaces the matched node. Any text node containing only
$0
within the contents of the spec will be replaced by a complete copy of the matched node, effectively wrapping the matched node.<xpath expr="//field[@name='x_field']" position="replace"> <div class="wrapper"> $0 </div> </xpath>
- attributes
the content of the inheritance spec should be
attribute
elements with aname
attribute and an optional body:if the
attribute
element has a body, a new attributed named after itsname
is created on the matched node with theattribute
element’s text as valueif the
attribute
element has no body, the attribute named after itsname
is removed from the matched node. If no such attribute exists, an error is raisedif the
attribute
element has anadd
attribute, aremove
attribute, or both, the value of the matched node’s attribute named aftername
is recomputed to include the value(s) ofadd
(separated byseparator
) and delete the value(s) ofremove
(separated byseparator
). Ifseparator
is not provided,,
is used instead.
<field name="x_field" position="attributes"> <attribute name="invisible">True</attribute> <attribute name="class" add="mt-1 mb-1" remove="mt-2 mb-2" separator=" "/> </field>
- move
can be used as a direct child of a inheritance spec with a
inside
,replace
,after
orbefore
position
attribute to move a node.<xpath expr="//@target" position="after"> <xpath expr="//@node" position="move"/> </xpath> <field name="target_field" position="after"> <field name="my_field" position="move"/> </field>
Model Commons¶
- Model.get_views(views, options=None)[source]¶
Returns the fields_views of given views, along with the fields of the current model, and optionally its filters for the given action.
The return of the method can only depend on the requested view types, access rights (views or other records), view access rules, options, context lang and TYPE_view_ref (other context values cannot be used).
Python expressions contained in views or representing domains (on python fields) will be evaluated by the client with all the context values as well as the record values it has.
- Parameters
views – list of [view_id, view_type]
options (dict) –
a dict optional boolean flags, set to enable:
toolbar
includes contextual actions when loading fields_views
load_filters
returns the model’s filters
action_id
id of the action to get the filters, otherwise loads the global filters or the model
- Returns
dictionary with fields_views, fields and optionally filters
- Model.get_view([view_id | view_type='form'])[source]¶
Get the detailed composition of the requested view like model, view architecture.
The return of the method can only depend on the requested view types, access rights (views or other records), view access rules, options, context lang and TYPE_view_ref (other context values cannot be used).
- Parameters
view_id (int) – id of the view or None
view_type (str) – type of the view to return if view_id is None (‘form’, ‘tree’, …)
options (dict) – boolean options to return additional features: - bool mobile: true if the web client is currently using the responsive mobile view (to use kanban views instead of list views for x2many fields)
- Returns
composition of the requested view (including inherited views and extensions)
- Return type
- Raises
if the inherited view has unknown position to work with other than ‘before’, ‘after’, ‘inside’, ‘replace’
if some tag other than ‘position’ is found in parent view
Invalid ArchitectureError – if there is view type other than form, tree, calendar, search etc… defined on the structure