首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何正确使用self.env.commit()?

如何正确使用self.env.commit()?
EN

Stack Overflow用户
提问于 2022-01-27 19:47:07
回答 1查看 1K关注 0票数 1

请有人向我解释一下self.env.cr.commit()是如何工作的,什么时候使用它,以及一些好的实践?

从Odoo文档来看,使用cr.commit似乎非常危险。这是我第一次使用它,我不知道如何在用例中正确地使用它。

编辑:

关于我的用例的更多信息:我正在通过发货提供者API创建出货量。假设我的API调用是成功的,并且我已经创建了托运,但是在处理响应过程中,由于某种原因,我必须提高UserError,并且我的更改是回滚的。因此,现在装运的状态在Odoo和运输提供者服务器上是不同的,这是不可接受的。

因此,如果我调用的方法是create_dhl_shipment(),而标志变量是True (上次调用期间发生了错误),那么我想删除最初的发货并创建一个新的。

和我的问题是:如何对数据库进行更改并防止其回滚.

在互联网搜索过程中,我偶然发现了cr.commit(),但是文档中的Odoo确实不鼓励使用它。

非常简单的例子:

代码语言:javascript
运行
复制
Class StockPickingInherited(models.Model)
    _inherit = 'stock.picking'

    remnant_shipment = fields.Boolean("Possible remnant shipment")
    packages = fields.One2many("stock.shipment.package", "picking_id")
    
    def create_dhl_shipment(self):
        response_from_shipping_provider = requests.get("API URL")
        if response_from_shipping_provider != 200:
            if not remnant_shipment:
                raise UserError("Shipment creation failed")
            else:
                self.write({"packages" : [(5, 0, 0)]})
                self.env.cr.commit() # write data into the db and keep the change from rollbacking due to raising UserError
                raise UserError("Shipment creation failed")

我做得对吗?有潜在的危险吗?

EN

回答 1

Stack Overflow用户

发布于 2022-01-28 11:56:07

的确,self.env.cr.commit()应该被谨慎地使用。然而,它有一些合法的用例。例如:

代码语言:javascript
运行
复制
@api.model
def some_cron_job(self):
    for record in self.env[...].search(...):
        record.do_some_process()
        self.env.cr.commit()

上面的内容是可以的,因为您正在对一批记录执行某些处理,并且为了避免cron作业由于其中一条记录上的错误而重复执行,您可以在处理完每条记录之后提交。(PS:使用try...except可以使上述情况更安全.或者将记录标记为“失败”,例如。这可以与commit()一起完成)

在您的用例中,您希望向用户显示一条消息,但是您的问题是,一旦您raise事务将回滚,因此要解决这个问题,您可以调用一个commit()

我也遇到过类似的情况,有时我发现使用@api.onchange可以很好地向用户显示消息。

代码语言:javascript
运行
复制
@api.onchange('your_field')
def onchange_your_field(self):
    if self.your_field > 100:
        raise UserError("Thanks for entering the field")

但是,我不再喜欢这种方法,因为Odoo已经摆脱了大多数@api.onchange,而倾向于使用计算字段。(这一举动有很好的理由,所以也要尽量避免。)

幸运的是,在Odoo13.0版中引入了一种新的方法。

代码语言:javascript
运行
复制
def some_method(self):
    # Do something
    self.write({"something" : False})
    # Display message
    return {
        'type': 'ir.actions.client',
        'tag': 'display_notification',
        'params': {
            'title': title,
            'message': message,
            'sticky': False,
        }
    }

以上内容取自Odoo中的这里,如果邮件服务器凭据正确,将向用户显示一条消息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70884813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档