记一次M2O字段创建报错调试

起因

image.png

一个简单的form页面,根据入库单据的选择,带出对应的明细行,而在明细行中入库单行即为一个M2O字段关联了入库明细行,就在这个保存这个表单时报了下面的错误提示

Traceback (most recent call last):
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 640, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 677, in dispatch
    result = self._call_function(**self.params)
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 333, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\service\model.py", line 101, in wrapper
    return f(dbname, *args, **kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 326, in checked_call
    result = self.endpoint(*a, **kw)
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 935, in __call__
    return self.method(*args, **kw)
  File "D:\odoo\gooderp_\openobject\odoo\http.py", line 506, in response_wrap
    response = f(*args, **kw)
  File "D:\odoo\gooderp_\openobject\odoo\addons\web\controllers\main.py", line 885, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\addons\web\controllers\main.py", line 877, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\api.py", line 687, in call_kw
    return call_kw_model(method, model, args, kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\api.py", line 672, in call_kw_model
    result = method(recs, *args, **kwargs)
  File "D:\odoo\gooderp_\myaddons_gooderp\hui_change_cost\models\change_cost.py", line 180, in create
    return super(ChangeCost, self).create(vals)
  File "D:\odoo\gooderp_\gooderp\good_process\models\mail_thread.py", line 191, in create
    thread_row = super(MailThread, self).create(vals)
  File "D:\odoo\gooderp_\openobject\odoo\addons\mail\models\mail_thread.py", line 228, in create
    thread = super(MailThread, self).create(values)
  File "D:\odoo\gooderp_\gooderp\core\models\core.py", line 38, in create
    record_id = create_original(self, vals)
  File "D:\odoo\gooderp_\openobject\odoo\models.py", line 3826, in create
    record = self.browse(self._create(old_vals))
  File "D:\odoo\gooderp_\openobject\odoo\models.py", line 3975, in _create
    field.write(self.with_context(rel_context), vals[name])
  File "D:\odoo\gooderp_\openobject\odoo\fields.py", line 2215, in write
    comodel.create(act[2])
  File "D:\odoo\gooderp_\gooderp\core\models\core.py", line 38, in create
    record_id = create_original(self, vals)
  File "D:\odoo\gooderp_\openobject\odoo\models.py", line 3826, in create
    record = self.browse(self._create(old_vals))
  File "D:\odoo\gooderp_\openobject\odoo\models.py", line 3921, in _create
    cr.execute(query, tuple(u[2] for u in updates if len(u) > 2))
  File "D:\odoo\gooderp_\openobject\odoo\sql_db.py", line 154, in wrapper
    return f(self, *args, **kwargs)
  File "D:\odoo\gooderp_\openobject\odoo\sql_db.py", line 231, in execute
    res = self._obj.execute(query, params)
ProgrammingError: ARRAY types integer and boolean cannot be matched
LINE 1: ...0', NULL, 35, '0.0000', 1, '0', NULL, ARRAY[7295, false], NU...

翻译过来的意思就是数据库中整型字段不能填入一个数组格式,正常一个M2O存入数据库中应该是一个id值为什么会变成一个数组呢?

追踪过程

前端页面保存一个新的记录肯定是调用模型的create方法,重写create打印创建字典

image.png

确实这个in_move_line字段的值变成了一个数组,但是仔细看uom_id也是个M2O字段,但它确实正常id值,所以继续从前端传值查追查看什么时候这里变成了数组

image.png

从前端create的请求参数中发现,这个in_move_line还是一个数组,继续往调用堆栈中查找什么时候变成了数组,
data_model.js 中rpc调用的后端create方法,-->data.js中的create方法,-->orm_view.js中的_process_save方法
image.png

最终找到create的值是在_process_save方法中的get_value中获取各个字段的值,最终在form_relational_widgets.js中找到O2M的get_value方法,在该方法中有对M20取值的方法:

                // format many2one values
                for (var k in values) {
                    if ((values[k] instanceof Array) && values[k].length === 2 && typeof values[k][0] === "number" && typeof values[k][1] === "string") {
                        values[k] = values[k][0];
                    }
                }

注意这里的判断: 如果字段是一个数组且数组长度为2,数组第一个元素是数字类型,第二个元素是字符串类型,那么就会将这个数字的第一个元素,也就是M20字段的id值取出来,而我的问题恰恰就出在数组中的第二个元素是false,并不是字符串,到此我以为就是因为in_move_line中没有name字段的原因导致的为false,但经过其他模型M20的实验发现并不是,在前端中关系字段的默认格式应该是[id,model_name,id],第二个元素不可能是false,既然和原生的不一样,那么大胆猜测一下就应该是in_move_line的name_get方法被重写了吧,果然被我找到了重写方法(gooderp原生代码)

@api.multi
def name_get(self):
  res = []
  for line in self:
    if self.env.context.get('match'):
      res.append((line.id, '%s-%s->%s(%s, %s%s)' %
        (line.move_id.name, line.warehouse_id.name, line.warehouse_dest_id.name,
          line.goods_id.name, str(line.goods_qty), line.uom_id.name)))
    else:
      res.append((line.id, line.lot))
  return res

一般返回都是(line.id, line.lot),如果明细行没有批号就会导致false值

总结

  • 导致这个报错的原因一方面感觉odoo10前端中对这个判断不太恰当,第二个元素非要是字符串才可以,但是name_get这个方法也是经常重写用于替换M20展示名的,第二个方面就是gooderp中没有考虑到明细行中没批号的情况导致了false。

  • 这个问题估计也比较难复现,而且odoo的前端改动太大,在13中压根就没有form_relational_widgets.js文件,如果遇到类似问题的小伙伴,可以按这个思路去排查一下吧,解决方法就仁者见仁智者见智,比如一开始百思不得其解时我就暴力的重写create方法将list改回了id值.

  • 最后感谢一下Ruter大佬提供排查的思路

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容