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>
用户点击筛选按钮选择「自定义」即可输入起止日期,系统自动返回对应范围的报表数据。
方案二:自定义查询向导(符合指定输入日期的交互要求)
如果需要专门的参数输入页面,可创建向导模型供用户输入参数后跳转展示过滤后的数据:
- 新增向导模型
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', }
- 添加上下文菜单项或者动作按钮,让用户可以打开向导输入日期查询即可。
核心逻辑说明
Odoo的ORM在查询模型数据时,会自动将传入的domain参数转为SQL的WHERE条件拼接在查询语句后,性能和直接写在视图中几乎没有差异,同时可以支持任意动态参数的调整,完全满足你动态查询指定时间段数据的需求。
内容的提问来源于stack exchange,提问作者Ahmed Abd El Latif
相关产品推荐
相关产品推荐

