odoo13 定时任务【安排的动作】的实现与需要注意的问题
程序员文章站
2022-07-15 16:17:01
...
今天有这么一个需求,给用户增加一个年龄字段,依赖生日字段取计算。
刚开始想用计算字段和@api.depends 去实现,但后来发现客户已经有一万条了。而且我这个年龄字段是要存储到数据库的。第一,计算字段要保存到数据库(store=True),页面的加载并不会根据依赖字段去计算,那么,只有手动取修改日期的话,才会计算并存储。数据已经有10000+了,我不可能一条一条的改一下日期。第二,这个年龄是岁当前时间在变化的,这次改了,过几天可能就不是这个年龄了。
我想到了odoo里的定时任务,让服务器去做。
新建 data/ir_cron_data.xml 并在__manifest__.py中引用
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="ir_cron_auto_calculate_age" model="ir.cron">
<field name="name">自动计算年龄</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="True"/>
<field name="model_id" ref="model_res_partner"/>
<field name="code">model._compute_age()</field>
<field name="state">code</field>
</record>
</odoo>
上面的几个属性:
name 自动任务的名称
interval_number 和 interval_type 指的是执行频率和执行周期类型,比如:这里为interval_number为1,interval_type为days,就是每天执行1次一次定时任务。
numbercall 是指这个任务一共执行的次数,比如10,那么任务执行10次后将不再执行,这里填写-1,代表一直执行下去。
doall 在服务器重启期间错过了执行时机,是否再次补充执行。
model_id 任务方法所在模型, 格式 model_ + 模型名(res.partner 写成 res_partner,把 . 换成 _ )
state 和 code ,表示这个任务 的功能由代码实现,code 的值格式 model.方法名(),不要忘记方法名后面的括号
接下来,就是编写code指向的方法的代码:
def _compute_age(self):
res = self.env['res.partner'].search([])
for record in res:
if record.birthday:
age = self._calculate_age(record.birthday)
record.write({"age": age})
else:
record.write({"age": 0})
需要注意的几点:
- 将这个代码,写到 model_id 指向的模型中
- 在方法中,不要直接使用 for record in self , 使用self 是无效的,你需要 使用 env 将记录集取出来,在进行操作。
下面是安装后,在安排的动作中,看到的样子