odoo 开发 - 按钮修改字段状态

Odoo按钮操作与字段状态变更
本文介绍在Odoo中如何通过按钮操作修改模型字段的状态,包括从'临时'到'正式'的确认过程,以及从'正式'回退到'临时'的功能实现。通过定义模型方法和在XML中配置按钮,实现工作流状态的转换。

odoo 开发 - 按钮修改字段状态

确定按钮及回退按钮

简单按钮功能,点击修改字段状态

model 文件
jobstatus = fields.Selection([
        ('1', '正式'),
        ('2', '临时'),
        ('3', '作废'),
    ], default='2', string='单据状态')

@api.multi  # 确定按钮,更改:临时 - > 正式
def button_confirm(self):
    return self.write({"jobstatus": "1"})

@api.multi  # 回退确定按钮   更改: 正式 -> 临时
def button_back_to_determine(self):
    return self.write({"jobstatus": "2"})
xml 文件
<header>
    <button name="button_confirm" string="确定" type="object" class="btn-primary"/>
    <button name="button_back_to_determine" string="回退确定" type="object" class="btn-primary"/>
</header>



点击修改状态

在这里插入图片描述

<think>我们正在处理一个关于Odoo tree视图的问题:如何在字段列中添加按钮。 在Odoo中,tree视图(也称为列表视图)通常用于显示多条记录的列表。默认情况下,字段以只读文本形式显示。但有时我们可能希望将某个字段显示为按钮,以便用户点击执行操作。 解决方案: 我们可以使用`<field>`元素的`widget`属性来改变字段的显示方式。Odoo提供了一些内置的小部件(widgets),其中就有`button`小部件,可以将字段渲染为按钮。 步骤: 1. 在tree视图中,为需要显示为按钮字段添加`widget="button"`属性。 2. 可以设置按钮的属性和事件,例如定义点击按钮时调用的方法。 示例: 假设我们有一个模型`my.model`,其中有一个字段`my_field`,我们希望在tree视图中将其显示为按钮。 在视图定义中,我们可以这样写: ```xml <tree> <field name="my_field" widget="button" options='{"type": "object", "name": "my_button"}'/> </tree> ``` 但是,请注意,使用`widget="button"`时,默认情况下点击按钮会触发该记录的`onclick`事件。我们可能需要在模型中定义相应的方法来处理按钮点击。 另外,我们还可以通过`options`属性传递一些额外的选项。例如,我们可以指定按钮的类型(普通按钮、对象按钮等)和按钮的名称(用于在事件中区分)。 然而,仅仅这样可能还不够,因为按钮需要绑定一个动作。通常,我们可以通过以下两种方式之一: a) 在模型的方法中定义一个方法,当按钮点击时调用。例如,我们可以定义一个方法`action_my_button`,然后在视图中指定该按钮的动作。 b) 使用`@api.onchange`或通过按钮事件触发一个动作。 但是,在tree视图中,按钮小部件默认会尝试调用模型中的一个方法,该方法名由按钮字段名和`_button`后缀组成。例如,如果字段名为`my_field`,则点击按钮时会调用`my_field_button`方法。 因此,我们还需要在模型中定义一个方法,比如: ```python def my_field_button(self, record): # 处理按钮点击事件 # 这里的record是当前记录 pass ``` 但是,实际上,在Odoo中,按钮小部件在tree视图中的行为是:点击按钮时,会调用模型中的一个方法,方法名为`button_`加上字段名(或通过options指定的方法名)。因此,我们需要根据Odoo的约定来定义方法。 更准确的做法是: 1. 在视图中定义按钮: ```xml <field name="my_field" widget="button" options='{"type": "object", "name": "my_button", "action": "my_button_action"}'/> ``` 这里,我们通过options指定了一个动作`my_button_action`,这将是模型中的方法名。 2. 在模型中定义方法`my_button_action`: ```python def my_button_action(self): # 处理按钮点击事件,self是当前记录集(在tree视图中,由于是逐行点击,所以通常self是单条记录) pass ``` 注意:在tree视图中,当点击按钮时,Odoo会将当前记录作为参数(通过上下文)传递给方法,因此方法中的`self`是当前点击的记录。 另外,我们也可以不指定`action`,那么按钮小部件会尝试调用一个默认的方法,方法名为`button_action_`加上字段名。例如,字段名为`my_field`,则方法名为`button_action_my_field`。 因此,另一种写法是: ```xml <field name="my_field" widget="button"/> ``` 然后在模型中定义: ```python def button_action_my_field(self): # 处理按钮点击事件 pass ``` 但是,请注意,这种方法名是Odoo的默认约定,可能会因版本而异。 为了确保兼容性,建议显式指定`action`。 此外,我们还可以设置按钮的样式、图标等,但通常按钮小部件会使用字段的值作为按钮的文本。如果我们希望按钮显示固定的文本或图标,我们可以: - 在模型中定义一个计算字段,该字段返回固定的文本(如“点击我”),然后将该字段用于按钮- 或者,使用`<button>`元素而不是`<field>`元素,但这通常用于整个行的操作,而不是针对特定列。 如果我们想要在列中显示一个按钮(而不是将字段值显示为按钮),我们还可以考虑使用`<tree>`的`<button>`元素,但这通常是在每行的开头或结尾添加按钮列,而不是在特定字段列中。 因此,总结一下,在字段列中添加按钮的步骤: 1. 在tree视图中,使用`<field name="your_field" widget="button">`,并通过`options`指定动作方法名(可选,如果不指定则使用默认方法名)。 2. 在模型中定义相应的方法来处理按钮点击。 注意:按钮小部件要求字段值不能为空,否则按钮将不可见(因为显示为空)。因此,确保该字段有值,或者使用一个计算字段来提供固定的值。 示例代码: 模型(my_model.py): ```python from odoo import models, fields, api class MyModel(models.Model): _name = 'my.model' my_field = fields.Char(string="My Field", default="Click Me") # 默认值确保有显示文本 def my_button_action(self): # 当按钮点击时,执行此方法 # 可以在这里写具体的业务逻辑 self.write({'my_field': 'Clicked!'}) # 例如,修改字段值 # 或者触发其他操作 return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': f'Button clicked on record {self.id}', 'type': 'success', 'sticky': False, } } ``` 视图(my_model_view.xml): ```xml <record id="view_my_model_tree" model="ir.ui.view"> <field name="name">my.model.tree</field> <field name="model">my.model</field> <field name="arch" type="xml"> <tree> <field name="name"/> <field name="my_field" widget="button" options='{"action": "my_button_action"}'/> </tree> </field> </record> ``` 这样,在tree视图中,`my_field`列将显示为按钮点击按钮会调用模型的`my_button_action`方法。 注意:如果字段值为空,按钮将不显示。因此,确保字段有值(如设置默认值或通过计算字段提供值)。 另外,我们也可以使用一个固定的文本来显示按钮,而不依赖于数据库中的值。这时,我们可以使用一个计算字段,该字段返回固定的文本,然后将其用作按钮。 例如,在模型中添加: ```python button_text = fields.Char(string="Button Text", compute="_compute_button_text", store=False) def _compute_button_text(self): for record in self: record.button_text = "Click Me" ``` 然后在视图中使用这个计算字段: ```xml <field name="button_text" widget="button" options='{"action": "my_button_action"}'/> ``` 这样,无论数据库中的值如何,按钮都会显示“Click Me”。 以上就是在Odoo tree视图中给字段列添加按钮的方法。 根据引用[2]中提到的,我们在视图定义中保存后,需要重新加载页面来查看变化。 相关问题: 1. 如何在Odoo中为tree视图添加自定义按钮列(使用`<button>`元素)? 2. Odoo按钮小部件(widget)支持哪些事件和属性? 3. 如何为Odoo tree视图中的按钮设置不同的样式(如颜色、图标)? 4. 在Odoo中,如何根据记录的状态动态改变按钮的显示?</think>在 Odoo 的 tree 视图(列表视图)中为字段列添加按钮,可以通过以下两种主要方法实现: ### 方法一:使用 `widget="button"` 属性 (推荐) 这是最直接的方式,通过字段的 `widget` 属性将普通字段渲染为按钮: ```xml <tree> <field name="your_field" widget="button" options='{"type": "object", "name": "action_name"}'/> </tree> ``` **关键参数说明:** - `name`:要显示为按钮字段- `widget="button"`:指定按钮小部件 - `options` 配置: - `"type"`:`"object"` (调用模型方法) 或 `"action"` (触发窗口动作) - `"name"`:模型方法名或窗口动作的 XML ID **模型端实现示例:** ```python def action_name(self): # 按钮点击后的业务逻辑 self.write({'state': 'done'}) return { 'type': 'ir.actions.client', 'tag': 'display_notification', 'params': { 'message': '操作成功!', 'type': 'success' } } ``` ### 方法二:使用自定义按钮列 当需要完全自定义按钮行为时: ```xml <tree> <button name="custom_action" type="object" icon="fa-check" class="btn-success" string="确认"/> </tree> ``` **参数说明:** - `name`:调用的模型方法名 - `type`:`"object"` (模型方法) 或 `"action"` (窗口动作) - `icon`:FontAwesome 图标类 - `class`:CSS 样式类 - `string`:按钮显示文本 ### 动态按钮显示控制 根据记录状态动态显示按钮: ```xml <button name="approve" type="object" icon="fa-check" attrs="{'invisible': [('state', '!=', 'pending')]}"/> ``` ### 完整示例 **XML 视图定义:** ```xml <record id="view_your_model_tree" model="ir.ui.view"> <field name="name">your.model.tree</field> <field name="model">your.model</field> <field name="arch" type="xml"> <tree> <field name="name"/> <field name="amount" widget="button" options='{"type": "object", "name": "open_details"}' string="查看详情"/> <button name="validate" type="object" icon="fa-check" class="oe_highlight" attrs="{'invisible': [('state', '!=', 'draft')]}" string="审核"/> </tree> </field> </record> ``` **模型方法实现:** ```python def open_details(self): return { 'name': '详情', 'type': 'ir.actions.act_window', 'res_model': 'your.model', 'view_mode': 'form', 'res_id': self.id, 'target': 'current' } def validate(self): self.write({'state': 'approved'}) return { 'type': 'ir.actions.client', 'tag': 'reload' } ``` ### 注意事项 1. 按钮字段必须有值(空值不显示按钮),可设置默认值: ```python my_button = fields.Char(default="点击操作") ``` 2. 使用 `attrs` 属性控制按钮可见性/禁用状态 3. 安全权限:确保用户有执行相关方法的权限 4. 按钮样式:使用 Bootstrap 类如 `btn-primary`, `btn-danger` 等 保存修改后,需刷新视图(浏览器 F5)或升级模块才能看到变化[^1]。 --- ### 相关问题 1. 如何为 Odoo tree 视图的按钮添加条件可见性控制? 2. 如何在按钮点击后刷新当前 tree 视图? 3. Odoo 中如何为不同用户组显示不同的操作按钮? 4. 如何为 tree 视图按钮添加自定义图标和样式? 5. 在 Odoo 15/16 中,tree 视图按钮的实现方式有何变化? [^1]: 添加字段_Odoo开发教程3-为表单视图添加字段。⚫ 其它重要字段,如 Model, View Type 和 Inherited View 使用默认值即可IV. 此时点击 Save & Close 按钮,然后在 Edit View: Form 窗口点击 Save 按钮在保存修改后重载联系人表单视图页面即可查看到变化,在大数浏览器中可以使用F5 快捷键来重载页面。这时打开任意联系人名片,可以看到右侧 Tags 字段下会多出一个新字段[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值