在 Odoo 中添加自定义页面

前些天群里的小伙伴问了些关于在 Odoo 管理后台自定义页面和 Widget 的问题,那我就来写一篇简短的内容,教大家如何创建自定义页面并引用第三方库。如果大家有看我之前写的基础教程的话,应该知道我们从一开始就是用的是 Odoo11 吧,从今天开始,我们的教程全都将基于 Odoo12 进行编写,所以在开始前,请确保你现在使用的是 Odoo12,或者跟随官方的安装指南安装好环境再开始今天的内容。

创建模块

话不多说,先用 scaffold 命令创建一个新的模块 custom_page,结构如下:

myaddons
└── custom_page
    ├── __init__.py
    ├── __manifest__.py
    ├── controllers
    ├── demo
    ├── models
    ├── security
    ├── static
    └── views

我将会通过使用 wired-elements 这个 Web Components 组件库创建一个简单的自定义页面,从而演示如何引入并使用第三方库。所以我们先准备好相关库,先下载好这个库,然后将它放到 static 目录下:

static
└── lib
   └── wired-elements
      └── wired-elements.bundled.min.js

以上的目录层级结构是约定俗成的,第三方 JS 库推荐都放在 static/lib 下。

创建页面

接下来是创建自定义页面,同样的在 static 下创建:

static
└── src
   └── xml
      └── base.xml

自定义的页面、JS 和 CSS 等资源文件,都按约定放置在 static/src 下,下面是自定义页面 base.xml 文件的内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <templates id="template" xml:space="preserve">
    
        <t t-name="DemoPage">
            <div class="container-fluid py-2 o_web_settings_dashboard">
                <div class="form-row">
                    <div class="col-12 col-lg-6 o_web_settings_dashboard_col">
                        <wired-card elevation="3">
                            <div class="mt8">
                                <wired-input placeholder="Enter name"></wired-input>
                            </div>
                            <div>
                                <wired-radio-group selected="two">
                                    <wired-radio name="one" text="Radio One"></wired-radio>
                                    <wired-radio name="two" text="Radio Two"></wired-radio>
                                    <wired-radio name="three" text="Radio Three"></wired-radio>
                                </wired-radio-group>
                            </div>
                            <div class="mt8 mr8 mb8 text-right">
                                <wired-button>Cancel</wired-button>
                                <wired-button elevation="3" class="demo-submit">Submit</wired-button>
                            </div>
                        </wired-card>
                    </div>
                </div>
            </div>
        </t>
    
    </templates>

页面中使用到了 wired-elements 的组件,具体使用方式请参考官方文档。上面的定义中,我们看到有一个属性 t-name,这个是页面的名称,可在 JS 中调用,这里暂不展开说明。

定义动作

自定义页面实际上是一个 client action,也就是客户端动作,通过对 AbstractAction 这个抽象类进行扩展,从而指定自定义页面的模板和页面的事件等,下面的代码定义了一个最简单的客户端动作,它包含了一个点击事件:

    odoo.define('custom_page.demo', function (require) {
    "use strict";
    
    var AbstractAction = require('web.AbstractAction');
    var core = require('web.core');
    
    var CustomPageDemo = AbstractAction.extend({
        template: 'DemoPage',
        events: { 'click .demo-submit': '_onSubmitClick' },
    
        _onSubmitClick: function (e) {
            e.stopPropagation();
            alert('Submit clicked!');
        }
    });
    
    core.action_registry.add('custom_page.demo', CustomPageDemo);
    
    return CustomPageDemo;
    
    });

上面这段代码的核心部分在 AbstractAction.extend(...) 中,其中 template 指定了自定义页面的模板名称,也就是我们前面所说的 t-name 这个属性,而 events 则定义了页面的一些事件,如该例中,定义的是当点击(click)带有类 .demo-submit 的元素时执行 _onSubmitClick 这个方法。

需要注意的是,我们需要通过 core.action_registry.add() 这个方法对动作进行注册,第一个参数表示注册的动作名(tag),第二个参数是要注册的动作对象。

创建菜单

既然自定义的页面是一个动作,那么我们就需要创建菜单和它进行关联,在 views/views.xml 定义菜单:

    <odoo>
        <data>
            <record id="action_custom_page" model="ir.actions.client">
                <field name="name">Custom Page</field>
                <field name="tag">custom_page.demo</field>
            </record>
    
            <menuitem
                    id="menu_root_custom_page"
                    name="Custom Page"
                    action="action_custom_page"
                    groups="base.group_user"
                    sequence="1"/>
        </data>
    </odoo>

加载资源

和普通页面一样,页面中所引用的 JS 或者 CSS 等资源文件,都需要在页面上引入才能使用,在 Odoo 中也不例外,不过有一点不同的是,Odoo 中有专门的集中引入资源文件的地方,这样做是为了将资源进行打包压缩,以减少请求的包体大小。

一般情况下都是在 views/templates.xml 中继承 web.ssets_backend 后在其末尾添加相关资源路径:

    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
        <data>
            <template id="assets_backend" name="custom page assets" inherit_id="web.assets_backend">
                <xpath expr="//script[last()]" position="after">
                    <script type="text/javascript" src="/custom_page/static/lib/wired-elements/wired-elements.bundled.min.js"></script>
                    <script type="text/javascript" src="/custom_page/static/src/js/demo.js"></script>
                </xpath>
            </template>
        </data>
    </odoo>

除了 JS 资源需要引入外,我们编写的页面模板也许要引入,打开 __manifest__.py 并在底部添加我们的自定义页面文件:

'qweb': ["static/src/xml/base.xml"]

OK! 大功告成,一个最简单的自定义页面已经完成了,安装模块然后运行看看效果吧。

开发者模式

很不幸的是,打开之后好像只有几个小点在页面,然后并没有什么东西了。先不慌,我们先打开设置页面,然后在页面最右侧那一列的底部,可以看到两个链接,分别是『激活开发者模式』和『激活开发者模式 (带 assets)』,我们点一下第二个带 assets 的链接,然后再次访问我们的自定义页面,结果如何?

Custom Page

那两个链接顾名思义,就是进入开发者模式,其中带 assets 的开发者模式会跳过执行资源打包的动作,在打开这个模式前,我们看到页面上的组件挤成一团了,是因为资源打包后导致 wired-elements 的部分属性无法找到。

注:以上操作只是为了演示说明相关功能,在生产环境中,强烈不建议任何非开发或运维人员进入开发模式进行操作。

源码都在仓库 Odoo-Tutorial-Demo 中,请先自己动手实操,遇到问题再下载源码安装查看,如果有其他难题可以提出来,我会抽空解答的~

<think>好的,用户想知道如何在Odoo 14中自定义应用页面。首先,我需要回顾一下Odoo自定义应用开发流程。记得Odoo的模块开发通常包括模型、视图、权限等部分。用户提到的引用中有提到使用scaffold命令生成应用框架,这可能是一个起点。引用[3]提到用odoo-bin scaffold生成应用,所以第一步应该是创建模块结构。 接下来,模型的定义。用户可能需要创建新的模型或者扩展现有模型。引用[4]里提到了给所有模型添加通用方法,但这里用户需要的是页面自定义,所以重点可能在视图部分。视图包括菜单、动作和具体的视图类型,比如树形视图、表单视图等。引用[1]提到了基础视图的写法,所以需要指导用户如何编写XML文件定义视图。 然后,权限和安全设置也是必须的,要确保新模块的访问权限正确配置,否则可能无法显示,如引用[2]中提到的Module搜索不到的问题,可能与权限或安装步骤有关。需要提醒用户正确配置访问控制列表(ACL)和菜单权限。 另外,Odoo 14可能有特定的注意事项,比如视图结构的变化或新的API使用方式。需要确认用户遵循Odoo 14的官方文档,避免使用过时的语法。引用[2]提到自定义模块无法搜索到的问题,可能涉及到模块未正确安装或清单文件(manifest)配置错误,所以需要检查__manifest__.py中的配置,确保包含正确的数据和依赖。 还需要考虑用户可能的错误点,例如视图XML文件中的错误导致页面无法加载,或者模型定义不正确导致字段不显示。建议用户逐步测试,安装模块后检查日志文件,查找可能的错误信息。 最后,生成相关问题时要涵盖用户可能进一步的需求,比如如何添加特定类型的视图,如何配置动作或菜单,以及如何处理常见的安装问题。确保问题覆盖用户可能遇到的后续步骤,帮助他们深入学习。</think>在Odoo 14中自定义应用页面主要通过模块开发和视图定制实现,具体步骤如下: ### 一、创建基础模块框架 1. 使用脚手架命令生成应用模板: ```bash ./odoo-bin scaffold 模块名 目标目录 ``` 引用案例显示该命令可快速创建模块结构[^3] ### 二、定义数据模型 在`models/`目录下创建模型文件: ```python from odoo import models, fields class CustomModel(models.Model): _name = 'custom.model' _description = '示例模型' name = fields.Char(string="名称") value = fields.Integer(string="数值") ``` 注意继承`models.Model`基类[^4] ### 三、视图定制(关键步骤) 1. **表单视图**: ```xml <record id="view_custom_model_form" model="ir.ui.view"> <field name="name">custom.model.form</field> <field name="model">custom.model</field> <field name="arch" type="xml"> <form> <sheet> <group> <field name="name"/> <field name="value"/> </group> </sheet> </form> </field> </record> ``` 2. **树形视图**: ```xml <record id="view_custom_model_tree" model="ir.ui.view"> <field name="name">custom.model.tree</field> <field name="model">custom.model</field> <field name="arch" type="xml"> <tree> <field name="name"/> <field name="value"/> </tree> </field> </record> ``` ### 四、菜单配置 在`views/menu.xml`中定义: ```xml <menuitry id="menu_root" name="自定义应用"/> <menuitry id="menu_sub" name="子菜单" parent="menu_root"/> <menuitry id="menu_action" name="数据列表" parent="menu_sub" action="action_custom_model"/> ``` ### 五、权限配置 在`security/ir.model.access.csv`中添加: ``` id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_custom_model,custom.model,model_custom_model,,1,1,1,1 ``` ### 六、模块安装 1. 将模块放入Odoo的`addons`目录 2. 开发者模式下进入`应用 → 更新应用列表` 3. 搜索并安装新模块 **注意**:若遇到模块无法搜索的问题,需检查: - `__manifest__.py`是否包含必要声明 - 模块目录是否在Odoo配置的插件路径中[^2] ### 七、视图扩展方法 使用XPath定位元素进行扩展: ```xml <xpath expr="//field[@name='name']" position="after"> <field name="new_field"/> </xpath> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值