如何修复ValueError:预期单例sale.order(41,...)

时间:2019-01-07 20:09:12

标签: odoo odoo-12

我已经编写了一个自定义的odoo模块,当我安装它时,它会引发单例错误。 当我注释掉_compute_margin(self)内部的所有内容,并仅返回0.0时,模块安装就很好。 然后,当我将_compute_margin函数改回原始函数并更新模块时,它会正常更新。

我需要进行哪些更改才能使模块使用_compute_margin函数的内容正确安装?

library(shiny)
library(leaflet)

Data <- data.frame(longitude = c(11, 12, 14), latitude = c(50, 49, 51))

mod_map_ui <- function(.id) {
  ns <- shiny::NS(.id)
  leafletOutput(ns("map"))
}

mod_map <- function(input, output, session, .Data) {
  output$map <- renderLeaflet({
    leaflet() %>% 
      addTiles() %>%
      addMarkers(data = .Data)
  })
}


ui <- fluidPage(
  uiOutput("list")
)

server <- function(input, output, session) {

  observe({
    tag.list <- tagList()
      for (i in seq_len(NROW(Data))) {
        tag.list <- tagAppendChildren(
          tag.list,
          mod_map_ui(paste0("map_mod", i)), br()
        )
        callModule(mod_map, paste0("map_mod", i), .Data = Data[i, ])
    }

    output$list <- renderUI({
      tag.list
    })
  })
}

shinyApp(ui, server)

2 个答案:

答案 0 :(得分:2)

您需要使用 @ api.multi 装饰您的计算方法。

基本上,当Odoo尝试初始化数据库中的新字段时,它将立即计算许多记录。当前设置方法的方式一次只能支持一条记录,这就是为什么收到 Expected singleton 消息的原因。

尝试以下操作:

# First, include the @api.multi decorator
@api.multi
@api.depends('order_line.margin')
def _compute_margin(self):
    # Second, use a for loop to loop over self
    # because it's possible for self to be multiple records
    for order in self:
        # Finally, use your same method logic in the loop...

        # Except that you must assign the result **per record**
        # in the loop (with `order` in this example instead of `self`)
        order.x_prsmarginpercentage = ...

the Odoo ORM Documentation

中查看更多详细信息

答案 1 :(得分:2)

将使用多个记录来调用计算方法,这些记录在self中提供。但是您尝试直接从self获取属性,该属性仅适用于单例(具有一个记录的记录集)。

因此,您有两种选择来解决该问题:

  1. 将您的方法重写为self上的for循环。您还应该使用@api.multi装饰该方法。简单的例子:
@api.multi
@api.depends('field1', 'field2', 'fieldn')
def _compute_my_field(self):
    for record in self:
        record.my_field = 4711
  1. 只需用@api.one装饰您的计算方法,以告诉Odoo为self中的每条记录循环执行。 Odoo将在self中的每个记录上循环,并将方法返回值收集在一个列表中,该列表将作为循环结束时的返回值。您可以以已经使用的方式使用self:作为单例。