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

Odoo17/18中base.view_users_form的groups_id字段定位失败问题

Odoo 17/18 自定义res.users视图时groups_id字段定位失败问题解决

问题重现

开发自定义模块继承base.view_users_form时,尝试通过XPath定位groups_id字段并设置隐藏,持续出现以下验证错误:

Validation Error
Error while parsing or validating view:
Element '' cannot be located in parent view

自定义视图代码如下:

<record id="view_users_form_inherit_seller" model="ir.ui.view">
    <field name="name">res.users.form.inherit.seller</field>
    <field name="model">res.users</field>
    <field name="inherit_id" ref="base.view_users_form"/>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='groups_id']" position="attributes">
            <attribute name="invisible">1</attribute>
        </xpath>
        <xpath expr="//page[@name='access_rights']" position="inside">
            <group name="user_type_group" string="User Type">
                <field name="groups_id" widget="radio" options="{'horizontal': true}" groups="base.group_system"
                       domain="[('category_id.name', '=', 'User types')]"
                       nolabel="1"/>
                <field name="user_type" widget="selection" options="{'no_create': True}" groups="base.group_system">
                    <option value="customer">Customer</option>
                    <option value="seller">Marketplace Seller</option>
                </field>
            </group>
        </xpath>
    </field>
</record>

原因分析

Odoo 17/18中,base.view_users_form的groups_id字段虽在原生视图结构中直接位于access_rights页面下,但实际视图渲染时可能被其他核心模块的继承视图修改了层级结构,导致全局XPath定位失效。此外,全局XPath定位容易受其他模块的视图继承影响,稳定性较差。

解决方案

1. 使用字段直接继承替代XPath

将原有的XPath定位改为直接通过<field>标签进行属性修改,这种方式不受视图层级变化影响:

<field name="groups_id" position="attributes">
    <attribute name="invisible">1</attribute>
</field>

2. 强化用户类型单选逻辑

为确保用户只能选择一种用户类型,除了前端使用radio widget外,建议通过后端约束强化逻辑:

from odoo import models, api, exceptions

class ResUsers(models.Model):
    _inherit = 'res.users'

    @api.constrains('groups_id')
    def _check_single_user_type(self):
        user_type_groups = self.groups_id.filtered(lambda g: g.category_id.name == 'User types')
        if len(user_type_groups) > 1:
            raise exceptions.ValidationError("用户不能拥有多种用户类型")

3. 完整修正后的视图代码

<record id="view_users_form_inherit_seller" model="ir.ui.view">
    <field name="name">res.users.form.inherit.seller</field>
    <field name="model">res.users</field>
    <field name="inherit_id" ref="base.view_users_form"/>
    <field name="arch" type="xml">
        <!-- 直接通过字段标签隐藏原生groups_id -->
        <field name="groups_id" position="attributes">
            <attribute name="invisible">1</attribute>
        </field>
        <!-- 在访问权限页添加用户类型选择组 -->
        <xpath expr="//page[@name='access_rights']" position="inside">
            <group name="user_type_group" string="User Type">
                <field name="groups_id" widget="radio" options="{'horizontal': true}" groups="base.group_system"
                       domain="[('category_id.name', '=', 'User types')]"
                       nolabel="1"/>
                <field name="user_type" widget="selection" options="{'no_create': True}" groups="base.group_system">
                    <option value="customer">Customer</option>
                    <option value="seller">Marketplace Seller</option>
                </field>
            </group>
        </xpath>
    </field>
</record>

额外建议

  • 避免依赖category_id.name过滤,建议为用户类型组创建专门类别,使用类别ID进行domain过滤(如[('category_id', '=', ref('your_module.user_type_category'))]),避免名称修改导致逻辑失效。
  • 若user_type是自定义字段,需在模型中正确定义,并添加与groups_id的联动逻辑,比如选择用户类型时自动关联对应权限组。

内容的提问来源于stack exchange,提问作者Red Science

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 05:07:05