1. Date类型字段给了默认值为当天,但是创建的时候与实际时间相隔一天(并不是时区的问题),如下:
这张图片为2月10日创建,默认值却是2月9日。
解决方法:
将date 、datetime类型字段默认值分别写如下样式
default=lambda self: fields.Date.today()
default=lambda self: fields.Datetime.now()
2.many2many字段保存后会自动排序,导致后续生成的明细无法按照自己的意图来,如下
具体码数字段原来关联了8,9,10,编辑然后添加1,2,3,保存后该字段会自动排序又变成1,2,3,8,9,10,此处应该是自动按照id来重排了(给该字段的关联模型添加_order属性使之无序也尝试过了,没用),很多时候我们不需要这样的自动排序(如我本想按照8,9,10,1,2,3的顺序遍历这个字段,但是它自动排序后遍历的顺序就变了)。
解决方法:新增加一个表,里面有两个字段,一个整数型,记录顺序;一个多对一,关联具体码数。然后使销售这个表多对多这个新表,就能将我们具体码数的选择顺序记录在这个新表中,因为调用write方法时,具体码数中的值还是按照我们选择的顺序来排的,它在保存之后才会自动按id来排,所以我们在write之前可以将这个顺序数据写进新表里,之后遍历新表就可以了。
3.kanban视图的继承
上方红色框内必须为extension,否则无效
元素标签的隐藏用上面两个方法均可
4.跳转至向导后,修改明细字段,当一条明细某个字段值为空时,该明细会直接删除
原因:工序字段设置了required="1",这种字段编辑后未填,向导模型并不会提示必填没填,而是会直接删除掉此数据。
解决方法:删除掉此字段的required="1"后即可解决问题。
5.将一个服务器的数据库复制到另外一个服务器上,登录后出现白屏如下
原因:odoo数据库里面的一些静态数据或者附件会存在一个以该数据库命名的文件夹中,当你移动、复制这个库到另外一个服务器上之后,如果你把这个数据库的名称改掉,它就会找不到这些静态文件,查看日志会有以下错误提示
解决方法:复制的数据库名称保持和原来一样即可解决
其他白屏问题现象:
备份出来的数据库在恢复到其他数据库上后,登录odoo显示空白页(非网络问题)。刷新,重启等方式都无法解决,经查找资料发现是由于静态css文件是存储在数据库之外的,数据库备份时静态文件和css文件不会一起备份,所以当还原数据库后,页面出现空白是由于静态文件路径是指定的,但是本地又没有,找不到导致的。
解决方法:
DELETE FROM ir_attachment WHERE url LIKE '/web/content/%';
执行完毕后,重启数据库服务以及odoo服务。
重启服务,升级base模块
然后还可能存在模块图标消失的问题,升级web模块
6.当我们给一些系统基础表,如res_partner,res_user,base这些表添加字段,会出现无法重启的情况,页面Internal Server Error 500,后台提示res_partner没有某某字段(还没升级当然没有,你倒是给我个升级的机会啊,在pycharm的启动器里添加-u 模块名也没法解决)。
解决方法:
a.新创建一个模块,将继承写到这个单独的模块里面,然后安装即可。此方法缺点:下次再需要在这个表添加新字段,还得新建模块。
b.直接去数据库找到这个表,给该表直接插入字段,简单粗暴,sql语句:
ALTER TABLE table-name ADD COLUMN cloumn-name varchar;
table-name为表名,cloumn-name为字段名, varchar为字段类型(根据实际需求来)
插入完成后,再重启服务就不会报错了。
c.在模型里添加以下代码
升级完记得注释掉,否则很影响速度
def __init__(self, pool, cr):
init_res = super().__init__(pool, cr)
cr.execute("""SELECT column_name
FROM information_schema.columns
WHERE table_name = 'res_users' -- 假设表在 public schema 中
""")
res=list(map(lambda item:item[0],cr.fetchall()))
if 'default_scan_workcenter_id' not in res:
cr.execute('ALTER TABLE res_users ADD COLUMN default_scan_workcenter_id varchar;')
if 'default_scan_print_id' not in res:
cr.execute('ALTER TABLE res_users ADD COLUMN default_scan_print_id varchar;')
if 'default_scan_gen_qty' not in res:
cr.execute('ALTER TABLE res_users ADD COLUMN default_scan_gen_qty numeric;')
return init_res
重启就不会报错了,就可以正常升级
d.重启完项目不要刷新页面(切记),直接去升级模块就行,这个是最方便的方法,前提是你重启后还没刷新页面。
7.tree视图字段添加装饰器atrrs="{'invisible':[('state', 'in', ('done', 'cancel'))]}"时,字段会隐藏值而不是隐藏整个字段,如果添加invisible="1"则是隐藏字段,如下
8.不可空继承。我在模块升级报错,提示如下
提示为某个xml文件上的视图出错,一开始以为是那个xml文件里多了个字符或者少了个字符啥的,然后仔细检查了那个xml文件好几遍也没有发现,然后进断点发现不是这个xml的问题,而是另外一个继承于此xml视图的问题。
原因:不可空继承。继承视图后,一定得写一些东西,而不是只继承,不写,如下。
9.docker-compose启动报错
windows上用docker-compose拉容器报错,提示如下
解决方法
10.数据库迁移问题解决方案,问题5的扩展
当出现白屏或者以下错误时:
原因:某某css加载失败,因为数据库迁移以后,ir_attachment表中存储的静态文件路径仍然是原路径,新环境中查找不到,然后就会报错
解决方法:删除ir_attachment表中的'url'字段以'/web/content'开头的所有数据
delete from ir_attachment where url ilike '/web/content/%';
然后升级base模块,问题解决
还可以再地址上加上 debug=assets,然后就能进去了,但是一关掉这个模式,还是会白屏,还是得执行上面的,把静态文件删除。
12.odoo域
search里面的domain,sale_ids是many2many字段,sale是单个单据,此时使用in也是可以的,可以匹配到sale_ids包含sale的。
13.点按钮弹出来的target='new'页面无法中的tree无法按照模型的_order属性或者tree视图上的default_order属性排序,需要手动排序后返回
14.计算方法和onchange方法里面尽量不上调用unlink(),调用后之前给表单赋值的操作会失效,尽可能其他等效果的方式来实现删除功能;unlink()应当在赋值之前进行,如果先赋值,后执行unlink,则赋值会失效,如:
self.qty = 10
self.partner_id.unlink()
则删除执行完成之后,self.qty并不等于10,而是变成0
15.模型one2many自己
_parent_name = "location_id"
给类添加此属性,类就可以one2many自己,具体可参考源生stock.location模型
16.browse方法,即使数据id不存在,也不会报错或者提示
比如 product_id = self.env['product.product'].browse(111111)
即使这个id 111111不存在,这行代码也不会有问题,而且还能用他来个其他字段赋值,如
self.product_id = product_id.id
当然,赋值完成后会报错,因为压根不存在这个id的产品
所以这个方法的使用最好搭配上exists方法,如下
if not order_id.exists():
raise UserError('产品不存在!')
17.docker容器down掉重新up后,odoo服务一直报错:KeyError: 'ir.http'
down掉服务后,重新up可能会报这个错误,这时需要将docker-compose里面的数据卷和服务名称改一下,由odoonetwork80 改成odoonetwork81
可能原因:服务重启拉起以后由于原来的networks已被占用,所以这里重新建一个就不会报错了
18.compute字段,没加store=True也无法进页面自动计算。
开始找了各种原因,最后发现是因为字段设置了company_dependent=True,导致无法运算
将company_dependent改成False即可
19.odoo新添加的css样式升级以后没有加载成功,刷新,重启都没有效果。
解决方法: ctrl+F5 (加载后台资源刷新,不同于直接F5刷新)
20.self.env.ref('#视图id') 这种方式读取视图数据会用到 ir.ui.view这个模型的read权限;当用户没有这个权限,但进行的操作里面有涉及到读视图的这个方法,就会引发权限错误,报错如下
解决方法:
a.给予该用户此权限
b.方法开始之前先加上以下代码,意思是超级用户执行逻辑
self = self.with_user(self.env.user).sudo()
21.给二进制文件添加显示名称
普通二进制字段添加上传文件后,保存后会显示为 ‘xxx kb千字节’ 字样,想要显示文件名称,需要如下操作,一定要记得加force_save=1:
22.向导模型onchange方法使用问题。
问题场景:点击按钮弹出向导模型(有明细),需要写的逻辑是在表头填写一个数字,按序将所填数值填充到明细上的数量字段上,大概样式如下;
开始写的逻辑是,点按钮,创建多条向导明细数据,然后return跳转到该向导窗口(new),然后填写表头的数字,自动填充下面明细,结果发现明细填充不了(页面上数值没变或者后台读取的数据没变),force_save='1'也加了,还是无济于事。
解决方法:点按钮不直接创建多条向导明细数据,而是用默认值形式,如下,然后问题得到解决,数据可以填充
23.导入模板
表单数据导入的时候默认是没有模板的,
如果想要自己提供模板,在该模型下添加以下方法
24.数字类型的字段(Float,Integer,Monetary)如果不加default=0.0的话,页面上会显示为0,但数据库中默认为空,并不是0。当我们筛选某个字段为0时会筛选不到这些单据,需要筛选某个字段为未设置,所以一般情况下,这些类型的字段最好添加default=0。
25.需求:动态创建tree视图字段,点击菜单出现选择日期范围的弹窗,选择日期后先删除之前的自定义字段,然后根据日期范围按每天生成以x_开头的自定义字段,按序添加到视图中去。
错误:按需求完成后,会报错,例如AttributeError: 'Char' object has no attribute 'depends'样式。
引发问题的原因:进过断点排查,最后发现是字段缓存造成的问题随意创建和删除自定义字段会影响缓存的正确读取,导致报错,甚至系统崩溃。
解决建议:将临时创建自定义字段改成类中定义固定数量的字段,加载视图之前更改这些字段element的string属性以达到相同效果;或者做定时任务删除自定义字段而不是进页面时删除字段(猜测,没实践过)。
26.跳转向导弹窗时会触发明细(如果明细是多对多字段且关联的不是向导模型)上的计算字段的计算方法,无论该计算方法是否添加store=True。
27.销售单确认报错如下:
错误原因:客户选择了本公司,导致产品补货路线出错。
解决方法,可以在销售单确认前判断客户是否为本公司。
28.onchange方法的赋值会触发计算方法,但是计算方法的赋值不会触发onchange。
29.附件权限问题,报错如下
这种一般都是附件上传时模型标识(res_id)和资源模型(res_model)没有正确的传值,导致无法确认附件所属表单,读的时候引发权限问题。
解决方法:去附件中将res_id和res_model值不全的附件删除后重新上传。
30.报错如下
原因猜测:某些字段修改了字段类型,导致数据库中的约束出现问题
解决方法:升级对应修改了字段类型的模块或者升级base.
31.Monetory类型字段在列表视图上加sum='合计'必须保证币种字段也在视图中(隐藏也行)才会触发合计效果,没加会是下图情况。另外如果列表视图多条数据币种不一致,合计也不会显示。