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

Odoo13看板视图跨状态拖动记录时必填字段未校验问题咨询

Odoo13 看板视图拖动记录跨列流转时触发必填校验的实现方案

Odoo13默认逻辑里,form视图上配置的字段必填规则仅在表单编辑保存时生效,看板视图下拖动记录跨状态列流转时,走的是单字段快速写入逻辑,不会加载form视图的校验规则,所以会出现必填字段为空也能改状态的问题。可以通过以下两层方案解决:

  • 后端模型层加全局校验(必做,从根源解决绕过问题)
    视图层的required属性本质是前端交互限制,所有非表单入口的操作(看板拖动、列表行内编辑、接口调用、批量修改)都不会触发这类校验,必须把必填规则写到模型层,才能保证所有写入场景都能触发校验。
    参考实现代码:

    from odoo import models, fields, api
    from odoo.exceptions import ValidationError
    
    class YourBusinessModel(models.Model):
        _inherit = 'your.actual.model.name'
    
        # 简单固定/条件必填直接写在字段定义上,写入时自动校验
        # 例:状态为done时,处理方案、完成时间为必填
        solution = fields.Text(string="处理方案", required=lambda self: self.state == 'done')
        finish_time = fields.Datetime(string="完成时间", required=lambda self: self.state == 'done')
    
        # 复杂多字段联动校验用约束方法实现
        @api.constrains('state', 'solution', 'finish_time', 'handler_id')
        def _check_state_required_fields(self):
            for rec in self:
                if rec.state == 'done':
                    missing_fields = []
                    if not rec.solution:
                        missing_fields.append('处理方案')
                    if not rec.finish_time:
                        missing_fields.append('完成时间')
                    if not rec.handler_id:
                        missing_fields.append('处理人')
                    if missing_fields:
                        raise ValidationError(f"记录流转到完成状态前,需补全以下必填项:{','.join(missing_fields)}")
    

    写完升级模块后,不管从哪个入口修改状态,只要必填字段为空,就会直接抛出校验提示,阻止状态变更。

  • 前端看板交互优化(可选,提升使用体验)
    后端校验是在写入时触发,报错时记录已经完成拖动动作后再弹提示,如果需要在拖动落位前就完成校验、不符合要求直接退回原位置,可以扩展看板组件的拖动事件,加一层前端前置校验。
    参考实现代码(存放到自定义模块的static/src/js/kanban_check.js路径下,并在模块资源清单中引入):

    odoo.define('custom_module.kanban_required_validator', function (require) {
        "use strict";
        const KanbanRenderer = require('web.KanbanRenderer');
        const core = require('web.core');
        const _t = core._t;
    
        KanbanRenderer.include({
            _onDropRecord: function (event, ui) {
                const targetState = event.currentTarget.dataset.groupByValue;
                const recordData = this._getDropRecord(event, ui).state.data;
                // 配置各状态对应的必填字段
                const stateRequiredMap = {
                    'done': ['solution', 'finish_time', 'handler_id']
                };
                const needCheckFields = stateRequiredMap[targetState] || [];
                const missing = [];
                needCheckFields.forEach(field => {
                    if (!recordData[field]) {
                        missing.push(this.fields[field].string);
                    }
                });
                if (missing.length) {
                    event.preventDefault();
                    // 将记录退回原位置
                    ui.placeholder.after(ui.draggable);
                    this.do_warn(_t('校验失败'), _t('流转到当前状态前需填写:') + missing.join('、'));
                    return;
                }
                return this._super.apply(this, arguments);
            }
        });
    });
    

    注意:前端校验仅做体验优化,不能替代后端校验,用户可以通过浏览器调试、接口调用等方式绕过前端规则,必须和后端模型层校验搭配使用。

踩坑提示:不要试图只修改视图xml的属性解决问题,所有视图层的规则都只对应当前视图的交互场景,数据层面的校验必须落回模型层实现。

内容的提问来源于stack exchange,提问作者David Santiago Correa Sierra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:27:27