准备一些操作(Action)?

到目前为止,我们主要通过声明字段和视图来构建模块。在任何真实的业务场景中,我们都希望将一些业务逻辑链接到操作按钮。在我们的房地产示例中,我们希望能够:

  • 取消或将房产设置为已售出
  • 接受或拒绝报价

有人可能会说,我们已经可以通过手动更改状态来完成这些事情,但这并不太方便。此外,我们还想增加一些额外的处理:当报价被接受时,我们想设定房产的售价和买家。

操作类型(Action Type)

参考:本主题相关文档可参考ActionsError management

在我们的房地产模块中,我们希望将些业务逻辑和一些按钮关联,最常见的做法是:

  • 在视图中添加一个按钮,比如在视图header部分:
<form>
<header>
<button name="action_do_something" type="object" string="Do Something"/>
</header>
<sheet>
<field name="name"/>
</sheet>
</form>
  • 将该按钮和业务逻辑关联:
from odoo import fields, models

class TestAction(models.Model):
_name = "test.action" name = fields.Char() def action_do_something(self):
for record in self:
record.name = "Something"
return True

通过将type="object"分配给我们的按钮, Odoo框架将在给定模型上执行带有name="action_do_something"的Python方法。

需要注意的第一个重要细节是,我们的方法名没有前缀下划线(_)。这使我们的方法成为一个公共方法,可以直接通过Odoo接口调用(通过RPC调用)。到目前为止,我们创建的所有方法(compute、onchange)都是在内部调用的,因此我们使用了前缀为下划线的私有方法。除非需要从用户界面调用方法,否则应始终将方法定义为私有。

还要注意,我们对self循环。始终假设可以对多个记录调用同一个方法;这有利于重用性。

最后,公共方法应该始终返回一些东西,以便可以通过XML-RPC调用它。当有疑问时,只需return True即可。

Odoo源代码中有数百个示例。其中一个例子是 视图中的按钮 和其对应的Python方法

<form class="o_lead_opportunity_form" js_class="crm_form">
<header>
<button name="action_set_won_rainbowman" string="Mark Won"
type="object" class="oe_highlight"
attrs="{'invisible': ['|','|', ('active','=',False), ('probability', '=', 100), ('type', '=', 'lead')]}"/>
...略
    def action_set_won_rainbowman(self):
self.ensure_one()
self.action_set_won() message = self._get_rainbowman_message()
if message:
return {
'effect': {
'fadeout': 'slow',
'message': message,
'img_url': '/web/image/%s/%s/image_1024' % (self.team_id.user_id._name, self.team_id.user_id.id) if self.team_id.user_id.image_1024 else '/web/static/src/img/smile.svg',
'type': 'rainbow_man',
}
}
return True

练习1

添加 ‘Cancel’ 和‘Sold’ 按钮到 estate.property 模型。已取消的房产不能被设置为已出售,已出售的房产不能被取消。

预期效果动画:

提示:为了抛出错误,可以使用 UserError 函数。

修改odoo14\custom\estate\views\estate_property_views.xml中的estate_property_view_form视图

    <record id="estate_property_view_form" model="ir.ui.view">
<field name="name">estate.property.form</field>
<field name="model">estate.property</field>
<field name="arch" type="xml">
<form string="estate property form">
<!-- header元素为本次新增 -->
<header>
<button name="set_property_sold" type="object" string="SOLD"></button>
<button name="set_property_canceled" type="object" string="CANCEL"></button>
</header>
<sheet>
<h1>
<field name="name"/>
</h1>
<p>
<field name="tag_ids" widget="many2many_tags"/>
</p>
<group>
<group>
<!-- state 字段为本次新增 -->
<field name="state" string="Status"></field>
<field name="property_type_id" string="Property Type"></field>
<field name="postcode" string="Postcode" ></field>
<field name="date_availability" string="Available From"></field>
</group>
<group>
<field name="expected_price" string="Expected Price"></field>
<field name="best_price" string="Best Price" />
<field name="selling_price" string="Selling Price"></field>
</group>
</group>
<notebook>
<page string="Description">
<group>
<field name="description"></field>
<field name="bedrooms"></field>
<field name="living_area"></field>
<field name="facades"></field>
<field name="garage"></field>
<field name="garden"></field>
<field name="garden_area"></field>
<field name="garden_orientation"></field>
<field name="total_area" string="Total Area"></field>
</group>
</page>
<page string="Offers">
<field name="offer_ids" />
</page>
<page string="Other info">
<group>
<field name="salesman_id" string="Salesman"></field>
<field name="buyer_id" string="Buyer"></field>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>

修改odoo14\custom\estate\models\estate_property.py

开头增加导入UserError

from odoo.exceptions import UserError

末尾新增以下代码

    def set_property_canceled(self):
if self.state == 'Sold':
raise UserError('不能取消已出售房产')
else:
self.state = 'Canceled' return True def set_property_sold(self):
if self.state == 'Canceled':
raise UserError('不能出售已取消房产')
else:
self.state = 'Sold' return True

重启服务,浏览器中验证

练习2

添加‘Accept’ 和‘Refuse’ 到estate.property.offer 模型。

预期效果动画:

提示: 把图标当按钮用,请查看这个例子

<button name="action_confirm" string="Confirm" states="draft" type="object" icon="fa-check"/>

修改odoo14\custom\estate\views\estate_property_offer_views.xmlestate_property_offer_view_tree

    <record id="estate_property_offer_view_tree" model="ir.ui.view">
<field name="name">estate.property.offer.tree</field>
<field name="model">estate.property.offer</field>
<field name="arch" type="xml">
<tree string="PropertyOffers">
<field name="price" string="Price"/>
<field name="partner_id" string="partner ID"/>
<field name="validity" string="Validity(days)"/>
<field name="deadline" string="Deadline"/>
<!-- button 为本次新增 -->
<button name="action_accept_offer" string="" type="object" icon="fa-check"/>
<button name="action_refuse_offer" string="" type="object" icon="fa-times"/>
<field name="status" string="Status"/>
</tree>
</field>
</record>

修改odoo14\custom\estate\models\estate_property_offer.py,最末尾添加以下代码

    def action_accept_offer(self):
self.status = 'Accepted'
self.property_id.state = 'Offer Accepted'
return True def action_refuse_offer(self):
self.status = 'Refused'
return True

重启服务,浏览器中验证

练习3

当报价被接受时,设定相应房产的买家和售价。

预期效果动画:

注意:在现实生活中,给定房产只能接受一个报价!

修改odoo14\custom\estate\models\estate_property_offer.pyaction_accept_offer函数如下

    def action_accept_offer(self):
self.status = 'Accepted'
self.property_id.state = 'Offer Accepted'
self.property_id.selling_price = 260000
self.property_id.buyer_id = self.partner_id
return True

重启服务,浏览器中验证

对象类型(Object Type)

“一些用户界面”章节中,我们创建了连接到菜单的操作。你可能好奇,是否可以连接操作到按钮。好消息,的确可以,其中一种实现方式如下:

<button type="action" name="%(test.test_model_action)d" string="My Action"/>

我们使用 type="action" 且在name中引用外部标识

odoo 开发入门教程系列-准备一些操作(Action)?的更多相关文章

  1. SeaJS入门教程系列之使用SeaJS(二)

    SeaJS入门教程系列之使用SeaJS(二) 作者: 字体:[增加 减小] 类型:转载 时间:2014-03-03我要评论 这篇文章主要介绍了SeaJS入门教程系列之使用SeaJS,着重介绍了SeaJ ...

  2. 移动H5开发入门教程:12点webAPP前端开发经验

    如果你是一名移动H5前端开发人员,25学堂的小编认为下面的分享的12点webAPP前端开发经验是你必须掌握的基础知识点.算是一篇移动H5开发入门教程吧! 1. viewport:也就是可视区域.对于桌 ...

  3. ActiveMQ详细入门教程系列(一)

    一.什么是消息中间件 两个系统或两个客户端之间进行消息传送,利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成.通过提供消息传递和消息排队模型,它可以在分布式环境下 ...

  4. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  5. 基于Nodejs生态圈的TypeScript+React开发入门教程

    基于Nodejs生态圈的TypeScript+React开发入门教程   概述 本教程旨在为基于Nodejs npm生态圈的前端程序开发提供入门讲解. Nodejs是什么 Nodejs是一个高性能Ja ...

  6. iOS开发入门教程

    iOS开发入门教程 http://my.oschina.net/mailzwj/blog/133273 摘要 iOS开发入门教程,从创建项目到运行项目,包括OC基础,调试,模拟器设置等相关知识. iO ...

  7. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...

  8. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

  9. ENVI Services Engine5.1 应用开发入门教程

    原文地址: ENVI Services Engine5.1 应用开发入门教程_ENVI-IDL中国_新浪博客 http://blog.sina.com.cn/s/blog_764b1e9d0102uy ...

  10. Android Studio JNI开发入门教程

    Android Studio JNI开发入门教程 2016-08-29 14:38 3269人阅读 评论(0) 收藏 举报  分类: JNI(3)    目录(?)[+]   概述 在Andorid ...

随机推荐

  1. 4、excel快速排序从1开始

    在分世界杯的文件时,要求把每一行从1开始排列,自己的做法就是先输入1和2,然后拖黑1和2,接着鼠标一直往下拖,这样就了. 公式的方法: 输入公式=Row()-1,如何在这个单元格的右下角双击就可以了 ...

  2. Django框架搭建web项目(三)

    参考官网文档:https://docs.djangoproject.com/zh-hans/4.0/intro/tutorial02/ 在生成的app中进行数据库表设计. 1.在路径H:\myproj ...

  3. UI自动化之【maven+selenium环境搭建】

    一.下载maven包 官网: http://maven.apache.org/download.cgi 二.配置maven环境变量  配置完之后验证一下:(若出现以下信息可看到maven的版本号就表示 ...

  4. Java (新)将Excel数据读取到ListMap

    Java (新)将Excel数据读取到ListMap Maven依赖: pom.xml <!-- excel --> <dependency> <groupId>o ...

  5. 最重要的Git命令行

    git命令行记录 Git 如何删除本地分支和远程分支 git checkout master git branch -a git push origin --delete dev 删除后,再次查看分支 ...

  6. CF1272 C Yet Another Broken Keyboard 题解+代码比对

    C. Yet Another Broken Keyboard time limit per test 2 seconds memory limit per test 256 megabytes inp ...

  7. Ndisuio win10 注册表下载

    看了一下应该没有什么隐私内容,丢失这个注册表信息会让网络服务无法启动,新建txt,复制后修改后缀为.reg,双击录入,在管理员权限下cmd中输入 netsh winsock reset 重启 Wind ...

  8. 解决Tomcat 启动,http://localhost:8080无法访问 问题

    注意:1:tomact能正常启动 2 : 通过startup启动后可以正常访问8080界面: 3: 通过eclipse启动后无法正常访问8080界面: Tomcat能在eclipse里面能正常启动,但 ...

  9. python跨文件之全局变量

    Python中的global关键字,你了解吗? - 知乎 (zhihu.com)  global 关键字 python跟C不一样,c是在一个文件定义后在另一个文件声明下是extern变量就好.pyth ...

  10. idea警告 breakpoints dramatically slow down

    idea启动项目提示的黄色警告 , 其实就是有地方断点之后 , 影响项目运行速 打开断点管理 , 查看具体是哪个影响了 , 断点不需要了及时取消