You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo中如何在XML文件使用不存储至数据库的计算字段

问题描述

我已经通过以下代码继承ir.model并创建了一个不存储到数据库的计算字段:

from odoo import api, fields, models, _
from odoo.http import request
class ir_models(models.Model):
    _inherit = 'ir.model'
    website_models = fields.Boolean('Allowed Website Model', compute='_is_website_models')
    @api.depends('website_models')
    def _is_website_models(self):
        for models in self:
            fields = request.env['ir.model.fields'].search([('model_id', '=', models.id)])
            for field in fields:
                if field.name == 'website_url':
                    models.website_models = True
                else:
                    models.website_models = False

现在想咨询:在Odoo中,如何在XML文件中使用这类不存储到数据库的计算字段?


解决方案

嘿,其实Odoo里非存储的计算字段(默认store=False)虽然没存在数据库里,但只要计算逻辑没问题,在XML视图和动作里的用法和普通字段差不太多,下面分几个常见场景给你说明:

1. 在视图里直接显示字段

最简单的用法就是把它加到树视图或表单视图里,和普通存储字段完全一样。比如给ir.model的树视图加这个字段:

<record id="view_ir_model_tree_website_inherit" model="ir.ui.view">
    <field name="name">ir.model.tree.website.inherit</field>
    <field name="model">ir.model</field>
    <field name="inherit_id" ref="base.view_ir_model_tree"/>
    <field name="arch" type="xml">
        <field name="name" position="after">
            <field name="website_models" string="Allowed for Website"/>
        </field>
    </field>
</record>

这样打开模型列表时,就能看到这个字段的布尔值了,系统会实时计算并显示。

2. 用做域条件过滤记录

你也可以用这个计算字段来过滤视图或动作里的记录,比如只显示那些有website_url字段的模型。不过要注意:非存储字段的域过滤是实时计算的,没法利用数据库索引,数据量大的时候可能会有点慢,小数据集完全没问题。

比如创建一个只显示允许网站模型的动作:

<record id="action_allowed_website_models" model="ir.actions.act_window">
    <field name="name">Website Allowed Models</field>
    <field name="res_model">ir.model</field>
    <field name="view_mode">tree,form</field>
    <field name="domain">[('website_models', '=', True)]</field>
</record>

或者直接给现有视图加默认过滤:

<record id="view_ir_model_tree_website_filter" model="ir.ui.view">
    <field name="name">ir.model.tree.website.filter</field>
    <field name="model">ir.model</field>
    <field name="inherit_id" ref="base.view_ir_model_tree"/>
    <field name="arch" type="xml">
        <xpath expr="//tree" position="attributes">
            <attribute name="domain">[('website_models', '=', True)]</attribute>
        </xpath>
    </field>
</record>

3. 关于分组和排序的限制

这里要提个坑:非存储字段没法用于服务器端的分组或排序(比如给树视图加group_by="website_models"),因为Odoo需要从数据库里取分组数据,而这个字段根本没存在库里。如果一定要做客户端分组,体验和性能都不太好,不建议这么用。

顺便给你的代码提个小优化

你的计算方法有两个小问题:

  • @api.depends('website_models')是错的,这个字段是计算出来的,不能依赖自己。应该依赖模型的字段集合,改成@api.depends('field_ids.name'),这样当模型的字段变化时,计算字段会自动更新。
  • 循环所有字段的写法效率不高,而且逻辑有问题(最后一个字段不是website_url的话会覆盖成False),可以改成更简洁高效的写法:
@api.depends('field_ids.name')
def _is_website_models(self):
    for model in self:
        # 直接判断是否存在website_url字段
        model.website_models = any(field.name == 'website_url' for field in model.field_ids)

另外,request.env在非HTTP场景(比如定时任务)下会报错,建议改成self.env,兼容性更好。

内容的提问来源于stack exchange,提问作者Avani Somaiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:28:34