odoo13二次开发总结

  • update()是调用js的改变前端数值,write()是在数据库层面改变数值
    建议当前页面@onchange修饰的方法内用update(),而其他页面的或者通过按钮改变的用write()

  •  
  • py文件更新则重启odoo,xml文件更新则升级模块(有特例,py里涉及字段增删的也要升级模块)
  • XML文件比较严格,但凡一点错odoo系统都要崩溃
  • models.py里的class内容一定不能为空,比如只写个pass,就会报错
  • xml继承只和ref和models有关
  • 如果有安装却看不到某模块,是因为设置里没给该用户分配访问权限
  • odoo中为错误的sql语句(比如update)写try是不起作用的,odoo的pgsql遇到这种会直接把事务给锁上。前面有错误的sql语句执行了,会直接锁住,就算finally写的正确sql语句也执行不了
  • 当field或button position='replace' 用不了的时候,试试改成xpath
  • xml标签内值为空是不可以的
  • odoo对非大量经验者真的是不友好、但是经验越多越轻松 /微笑
  • odoo的onchange所依赖的值,必须在前端显现出来,这个函数才会生效!!!
  • 并且,onchange方法修改值用的是前端方法,所以属性readonly是不能这样通过self.xxx来修改的
  • odoo的tree视图所含的字段,其model里的定义中不能写states=xxx,会读取不到state的
  • odoo的带有compute并且store=True字段,并且store=True的情况下,不能用self直接为其赋值,要报错的,需要这么写:
last_date = fields.Datetime('最后修改时间', compute='_compute_date', store=True)

@api.depends。。。
def _compute_date(self):
    # 更新最后修改时间
    for x in self:
        x.last_date = x.write_date

  • 单子底部的消息怎么搞?
  • 题外话,Pycharm在服务运行的时候,直接关软件的话,不要点Disconnect,这样只会断开pycharm和python,会让python.exe在后台运行,有好几次改py文件不生效都是它搞的鬼
  • compute,store的compute的字段不可加copy=False。 (貌似。。)
  • 在xml view里写domain,表示“或”用波兰表达式的'|'
    例如<field name="x" domain="['|', ('a', '=', True), ('b','=',True)]"/>
    但是如果想表示且的话就不是'&'了,而是什么都不加
    <field name="x" domain="[('a', '=', True), ('b','=',True)]"/>

  • 在写跳转出的小窗口的时候,明明在跳转函数return带上了context,为什么小窗口的子表的后台还是取不到context呢?
    是因为需要在xml里的 子表那个ids字段上面把context传进去,才可以接受得到
# stock.pack.operation模型
def action_split_lots(self):
    res = super(StockPackOperation, self).action_split_lots()

    res['context']['product_id'] = stock.product_id.id
    res['context']['location_id'] = self.location_id.id
    return res

<!--xml-->
<field name="pack_lot_ids" nolabel="1" context="{'product_id': context.get('product_id'),'location_id': context.get('location_id')}">
  • 附:后续domain过滤

因为弹窗这种默认的self是new object的对象,是没有加上父表的任何信息的,在未保存时是关联不到父表的,因此上述通过context传值进来

这里是想要接收父表跳转动作传递的location_id和product_id,然后对lot_id根据domain进行过滤

@api.onchange('lot_id')
def _onchange_lot_id(self):
    product_id = self._context.get('product_id')
    location_id = self._context.get('location_id')
    lot_ids = []
    stock_quant = self.env['stock.quant'].search([('location_id','=',location_id),('product_id','=',product_id),('qty','>','0')])
    for x in stock_quant:
        if x.lot_id.id:
            lot_ids.append(x.lot_id.id)
    domain = [('id', 'in', lot_ids)]
    return {'domain': {'lot_id': domain}}

  • 想要在模块安装的时候初始化一些数据,XML比较不优雅,所以采用在model层的,继承修改模块安装时调用的函数的方式,比如_auto_init(),来初始化数据
class DemoModel(models.Model):
    # ......
    @api.model_cr_context
    def _auto_init(self):
        # Here to write your code
        return super(DemoModel, self)._auto_init()
  • 更正,如果是新写的模型,为了初始化数据的话,上面的方法是错的,因为auto_init执行时,还没创建出该模型的数据表,auto_init之后才有数据表。
    所以改用init方法,是直接重写还是继承要看其他代码的地方有没有重写init。
def init(self):
    # Here to write your code

  •  
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值