目录
1、需求描述
点击下图中tree视图上的同步退货单按钮,弹出相应的form视图进行退货单同步,然后点击同步按钮调用后端python代码处理。
2、实现步骤
2.1 主要文件目录结构
2.2 js文件的创建
在static文件夹下面创建一个名为js的文件夹,编写相应的js文件
odoo.define('dms_gaunyi.list_sync_trade_return', function (require) {
"use strict";
var ListView = require('web.ListView');
var viewRegistry = require('web.view_registry');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function ($node) {
this._super.apply(this, arguments);
if (this.$buttons) {
this.$buttons.on('click', '.o_list_tender_bt_sync_trade_return', this._sync_equip_trade_return.bind(this));
}
},
_sync_equip_trade_return: function () {
var self = this;
self.do_action({
name: '同步退货单',
res_model: 'action.sync.trade.return',
views: [[false, 'form']],
type: 'ir.actions.act_window',
view_mode: 'form',
target: 'new',
});
}
})
})
define方法的第一个参数为名称,自行定义,require方法表示所用到的依赖,然后对按钮的点击事件绑定相应的方法,这个方法返回一个动作视图(就是所定义的瞬态模型的向导)。
2.3 创建按钮模板
也就是定义在/static/xml 文件夹下面的xml文件,用来定义所加的按钮
注意:此处所定义的class 与 js文件定位按钮时的class相对应
<?xml version="1.0" encoding="UTF-8"?>
<templates id="sync_trade_return" xml:space="preserve">
<t t-extend="ListView.buttons">
<t t-jquery=".o_list_buttons" t-operation="append">
<!-- 找到名为 "dms.trade.return"的模型,并在它的列表(tree)视图后面append一个按钮 -->
<t t-if="widget and widget.modelName == 'dms.trade.return'">
<!--btn表示按钮,btn-sm小按钮,btn-default默认按钮,btn-primary主要按钮?-->
<button class="btn btn-primary o_list_tender_bt_sync_trade_return" type="button">同步退货单</button>
</t>
</t>
</t>
</templates>
2.4 定义xml文件引入js代码
在views文件夹下面定义templates.xml文件,src对应js文件所在路径
注意:此处定义的xml文件需要在__manifest__文件中引入
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend" name="tree view menu" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/dms_core/static/src/js/trade_return.js"></script>
</xpath>
</template>
</odoo>
2.5 定义向导和所对应的动作视图
定义模型(继承自瞬态模型)和点击同步按钮所对应的方法。
class ActionSyncTradeReturnOrder(models.TransientModel):
_name = 'action.sync.trade.return'
_description = "同步退货订单"
channel = fields.Many2one('dms.sync.account', domain=[('channel', '!=', 'amazon')], required=True)
origin_no_code = fields.Char(string="发货单号", help="多个单号用英文字母”,“隔开")
def sync_defect_order(self):
...
视图部分(即action_sync_trade_return.xml文件)代码:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record model="ir.ui.view" id="sync_trade_form">
<field name="name">同步退货单</field>
<field name="model">action.sync.trade.return</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="channel" string="渠道"/>
<field name="origin_no_code" placeholder="多个单号用英文字母”,“隔开" attrs="{'required':1}"/>
</group>
<footer>
<button name="sync_defect_order" string="同步" type="object" class="btn-primary" />
<button string="取消" class="btn-secondary" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="action_sync_trade_return" model="ir.actions.act_window">
<field name="name">同步退货单</field>
<field name="res_model">action.sync.trade.return</field>
<field name="view_mode">form</field>
<field name="view_id" ref="dms_core.app_view_dms_trade_return_tree"/>
<field name="target">new</field>
</record>
</data>
</odoo>
3.问题解决
3.1 后台调用方法后视图不刷新?
在这个案例中,我遇到过同步数据后视图并没有立刻刷新数据,而要手动刷新的问题。
解决方法:
在python方法对数据处理之后返回一个动作视图,这个动作视图将跳转对应的tree视图,代码如下:
def sync_defect_order(self):
codes = self.origin_no_code.strip(' ').split(',')
m_name = 'action_sync_trade_return_from_code_%s' % self.channel.channel
.....
return {
'name': _('%s退货报告' % self.channel.name),
'res_model': 'dms.trade.return',
'view_id': False,
'type': 'ir.actions.act_window',
'view_mode': 'tree,form',
'domain': [('channel', '=', self.channel.channel)],
'context': {
'default_channel': self.channel.channel,
}
}
其中的res_model指的是最初界面的模型
3.2 当一个模型有多个tree视图的时候,如何在指定tree视图显示按钮?
我们在开发的过程中往往会继承已有的模型,从而一个模型就会有多个form视图或者tree视图,
但是我们在tree视图上定义按钮时不想在这个模型的所有视图上面定义,而是在这个模型指定的tree视图定义,这时候就需要在定义按钮的地方加上限制条件。代码如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<templates id="sync_check_duplicates" xml:space="preserve">
<t t-extend="ListView.buttons">
<t t-jquery=".o_list_buttons" t-operation="append">
<t t-if="widget and widget.modelName == 'res.partner' and widget.actionViews[0].fieldsView.name == 'cooperation.partner.tree'">
<!--btn表示按钮,btn-sm小按钮,btn-default默认按钮,btn-primary主要按钮?-->
<button class="btn btn-primary o_list_sync_check_duplicates" type="button">查重</button>
</t>
</t>
</t>
</templates>
其中有两个条件,res.partner表示按钮加在res.partner这个模型上面,第二个条件是定义的tree视图的id。