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

Odoo中基于SQL视图的模型如何获取用户动态输入参数

Odoo动态参数SQL视图报表实现方案

需求可实现,你当前写法存在核心问题

你原有逻辑的错误点:init() 方法仅在模块安装、升级阶段执行一次,SQL视图创建完成后WHERE条件中的起止日期就会被硬编码为执行时的默认值,完全无法响应用户后续的动态输入调整。

具体改造步骤

1. 调整原SQL视图模型,移除硬编码的日期条件

先修改视图定义,仅保留固定的过滤规则,所有动态参数相关的条件交给ORM层后续处理:

class SafeReportView(models.Model):
    _name = "ys.safe.report.3"
    _auto = False
    _description = "保险箱余额报表"

    sub_account_id = fields.Many2one(comodel_name="ys.sub.account", string="子账户")
    date = fields.Date(string="流水日期")
    debit = fields.Float(string="借方金额")
    credit = fields.Float(string="贷方金额")
    balance = fields.Float(string="余额")

    def init(self):
        tools.drop_view_if_exists(self._cr, 'ys_safe_report_3')
        self._cr.execute(""" 
        CREATE OR REPLACE VIEW ys_safe_report_3 AS (
            select 
                ROW_NUMBER() OVER (ORDER BY ysal.id) AS id, 
                ysa.id as sub_account_id, 
                ysal.debit as debit, 
                ysal.credit as credit, 
                ysal.balance as balance, 
                ysal.date as date
            from ys_sub_account_line ysal 
            inner join ys_sub_account ysa on ysal.sub_account_id = ysa.id 
            inner join ys_transaction yt on ysal.transaction_id = yt.id
            where ysa.name like 'Safe - %'
        )
        """)

注:移除了原代码中写死的日期过滤条件,同时删除了不需要存储的date1、date2字段,这两个字段仅作为查询参数使用

2. 实现动态传参查询,两种常用方案可选

方案一:使用列表视图自带筛选器(最简实现)

在该模型的搜索视图XML中添加时间段筛选配置,用户可直接在报表视图顶部选择起止日期自动过滤:

<record id="view_ys_safe_report_search" model="ir.ui.view">
    <field name="name">ys.safe.report.3.search</field>
    <field name="model">ys.safe.report.3</field>
    <field name="arch" type="xml">
        <search>
            <field name="sub_account_id"/>
            <!-- 时间段筛选组件 -->
            <filter string="流水日期" name="date_filter" date="date"/>
        </search>
    </field>
</record>

用户点击筛选按钮选择「自定义」即可输入起止日期,系统自动返回对应范围的报表数据。

方案二:自定义查询向导(符合指定输入日期的交互要求)

如果需要专门的参数输入页面,可创建向导模型供用户输入参数后跳转展示过滤后的数据:

  1. 新增向导模型
from odoo import models, fields, api
from odoo.exceptions import ValidationError

class SafeReportWizard(models.TransientModel):
    _name = "ys.safe.report.wizard"
    _description = "保险箱报表查询向导"

    date_start = fields.Date(string="开始日期", required=True, default=fields.Date.today)
    date_end = fields.Date(string="结束日期", required=True, default=fields.Date.today)

    @api.constrains('date_start', 'date_end')
    def _check_date_range(self):
        if self.date_start > self.date_end:
            raise ValidationError("开始日期不能晚于结束日期")

    def action_generate_report(self):
        # 构建筛选条件
        domain = [('date', '>=', self.date_start), ('date', '<=', self.date_end)]
        # 跳转返回报表视图
        return {
            'name': '保险箱余额报表',
            'type': 'ir.actions.act_window',
            'res_model': 'ys.safe.report.3',
            'view_mode': 'tree,form',
            'domain': domain,
            'target': 'current',
        }
  1. 添加上下文菜单项或者动作按钮,让用户可以打开向导输入日期查询即可。

核心逻辑说明

Odoo的ORM在查询模型数据时,会自动将传入的domain参数转为SQL的WHERE条件拼接在查询语句后,性能和直接写在视图中几乎没有差异,同时可以支持任意动态参数的调整,完全满足你动态查询指定时间段数据的需求。

内容的提问来源于stack exchange,提问作者Ahmed Abd El Latif

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:48:02