odoo 根据权限规则隐藏编辑按钮

业务分析

正常情况下odoo的编辑按钮是不会隐藏的,如果有权限限制会提示权限访问规则错误,也就是产生一个userError,这已经在用户毫不知情的情况下让用户实现了一系列无用的操作,这对用户很不友好,用户只有点击编辑,完成所编辑的内容之后再点击保存才知道无法保存。在这里插入图片描述改进和优化:我们直接将没有权限访问的用户让他看不到编辑按钮就ok了在这里插入图片描述
这样就避免了用户无效的点击,我们以第三方插件的形式

代码实现

注册的文件 manifest.py

{
    "name": "Edit button hide",
    "summary": "根据权限规则隐藏编辑按钮",
    "version": "14.0.1.0.0",
    "license": "AGPL-3",
    "category": "Web",
    "depends": [
        "web",
    ],
    "data": [
        "views/edit_button_hide.xml",
    ],
    "installable": True,
}

可以看到注册文件只需要一个xml文件,依赖的模块也仅仅是web,这里注意我们的程序要尽量少的依赖其他模块。

前端 js文件

我们可以看看form的展示函数,我们根据页详情案例每次进入的update方法进行跟踪,并重写update方法去添加按钮的展示的逻辑。

odoo.define("web_access_rule_buttons.main", function (require) {
    "use strict";
    # 应用form控制组件
    var FormController = require("web.FormController");
    # 重写form控制组件的update方法,update方法属于js异步方法,返回的是promise对象,根据异步回调的方法去获取返回值并进行操作
    FormController.include({
        async _update(state, params) {
            return this._super(state, params).then(this.show_hide_buttons(state));
        },
        # 按钮显隐的逻辑,获取id值,保证只在编辑的时候作用此规则,并发出rpc请求,进行后端交互
        show_hide_buttons: function (state) {
            var self = this;
            if (state.data.id){
                return self
                ._rpc({
                    model: this.modelName,
                    method: "check_access_rule_all",
                    args: [[state.data.id], ["write"]],
                })
                .then(function (accesses) {
                    self.show_hide_edit_button(accesses.write);
                });
            }

        },
        #根据后端的返回值进行按钮的显示和隐藏,找到按钮根据条件调用show和hide方法
        show_hide_edit_button: function (access) {
            if (this.$buttons) {
                var button = this.$buttons.find(".o_form_button_edit");
                if (button) {
                    // console.log(access)
                    if (!access){
                        button.hide()
                    }else {
                        button.show()
                    }
                }
            }
        },
    });
});

后端

我们根据rpc调用后端函数,达到回调显示的作用,后端方法进行权限的校验,并返回相应的参数

from odoo import exceptions, models


class Base(models.AbstractModel):
    """The base model, which is implicitly inherited by all models."""
    # 继承基础base模块,添加新方法
    _inherit = "base"
    # 校验规则
    def check_access_rule_all(self, operations=None):
        #以下注释是便于规范采用英文翻译,读者如果不理解可以自行利用翻译
        #翻译:识别相应操作的权限规则,返回操作的权限bool值,true代表有访问权限,false代表无访问权限
        """Verifies that the operation given by ``operations`` is allowed for
         the user according to ir.rules.
         If ``operations`` is empty, it returns the result for all actions.
        :param operation: a list of ``read``, ``create``, ``write``, ``unlink``
        :return: {operation: access} (access is a boolean)
        """
        # print(operations)
        if not operations or not any(operations):
            operations = ["read", "create", "write", "unlink"]
        result = {}
        for operation in operations:
            try:
                # 调用自己的校验权限规则方法,传入操作名称
                self.check_access_rule(operation)
            except exceptions.AccessError:
                result[operation] = False
            else:
                result[operation] = True
        return result

渲染文件

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    #继承web.assets_backend:这一资源包在 Odoo 的后台中使用(ERP 部分)。它包含所有与 web
客户端、视图、字段微件、动作管理器等相关的代码
    <template
        id="assets_backend"
        name="edit_button_hide assets"
        inherit_id="web.assets_backend"
    >
        <xpath expr="." position="inside">
            <script
                type="text/javascript"
                src="js文件的路径"
            />
        </xpath>
    </template>
</odoo>

测试文件

from odoo.tests.common import TransactionCase

#  测试对象和记录的规则
class TestAccessRuleButtons(TransactionCase):
    def setUp(self):
        super(TestAccessRuleButtons, self).setUp()
        self.curr_obj = self.env["res.currency"]
        self.curr_record = self.env.ref("base.USD")

    def test_check_access_rule_1(self):
        res = self.curr_obj.check_access_rule_all(["write"])
        self.assertFalse(res["write"])

    def test_check_access_rule_2(self):
        res = self.curr_record.check_access_rule_all(["write"])
        self.assertTrue(res["write"])

    def test_check_access_rule_3(self):
        res = self.curr_record.check_access_rule_all()
        self.assertTrue(res["read"])
        self.assertTrue(res["create"])
        self.assertTrue(res["write"])
        self.assertTrue(res["unlink"])

odoo 14 python 单元测试步骤

一.在模块根目录创建tests目录

二.在tests目录下创建__init__.py文件

三.继承TransactionCase(SingleTransactionCase、SavepointCase)类

四.实现setUp(self, *args, **kwargs)方法

五.以test_前缀为方法名,就是你的测试用例.

在测试用例中调用self.assertEqual方法来断言你的测试用例是否成功执行

六.TransactionCase、SingleTransactionCase、SavepointCase继承这三个不同的类,调用测试用例的情况都不一样

TransactionCase:

1.每一个测试用例是在单独的事务中运行的。

2.一旦测试用例方法运行成功,事务将自动回滚。

3.setUp方法在每次自动调用我们测试用例前都会调用一次,也就是有多少个测试用例就调用多少次setUp。

SingleTransactionCase:

1.所有测试用例都在同一个事务中执行。

2.因此从一个测试用例中产生的数据可以在另一个测试用例中使用。

3.事务从第一个测试用例开始,到最后一个测试用例结束时回滚。

SavepointCase:

1.测试方法运行在回滚的保存点中,而不是将所有的测试用例都放在一个事务中。

2.通过只生成一次测试数据来提高它们的速度。

3.这里,需要使用setUpClass()方法来生成初始化测试数据。

七.对测试类别进行标记.

1.标记可以决定执行测试用例是在安装模块前还是在安装模块后执行。

2.或者你还可以自定义标签。

3.运行的时候你可以指定标记执行测试用例

4.标准标记有:

standard(默认就有):默认会指定执行该标记的测试用例

at_install(默认就有):安装模块后立马执行测试用例

post_install:在所有模块安装完成后再执行测试用例

5.删除默认标记:在标记前面加-减号就代表删除该默认标记

八.注意:所有非标准测试用例将使用–test-enable 选项进行运行。要运行以上的测试用例,需要使用test-tags 选项如下(注意这里我们并不需要显式地传递 –test-enable 选项): 在测试用例的开发过程中,仅对一个模块运行测试用例非常重要。默认,模块的技术名称会添加为、标签,因此你可以使用模块的技术名称加–test-tags 选项。例如,如果你希望对 my_library 模块运行测试用例例如,如果你希望对 my_library 模块运行测试用例。 运行测试用例:./odoo‐bin ‐c server.conf ‐i my_library ‐‐test‐tags=my_library

翻译文件

msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module:edit_button_hide
#: model:ir.model,name:edit_button_hide.model_base
msgid "Base"
msgstr ""

总结

思想:做任何一件事情不要盲目的去实现,要有目的,人生在世,愿每个美好都能不期而遇,加油

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值