在實際的工作中我們經常需要定時完成一些操作,比如生成月度銷售報表。或者我們需要把一些計算量很大的操作放在夜間執行。這些都可以用定時任務來完成,odoo提供了對定時任務的支持,我們一起來看看。

在本示例中,我們創建一個定時任務,每2分鐘執行一次:循環遍歷資料庫表(scheduler.demo)上的所有記錄,每個記錄跟蹤任務程序運行了多少次。這個示例展示了定時任務如何與資料庫操作相結合。

創建模型和欄位

創建一個類文件scheduler_demo.py,內容如下

# -*- coding: utf-8 -*-

from odoo import models, fields, api, exceptions
import logging
from datetime import datetime
_logger = logging.getLogger(__name__)

class scheduler_demo(models.Model):
_name = scheduler.demo
name = fields.Char(required=True)
numberOfUpdates = fields.Integer(Number of updates)
lastModified = fields.Datetime(Last updated)

因為後面要用到日誌輸出,以及獲取系統時間,所以導入python的日誌模塊和時間模塊。

我們創建了scheduler.demo的新模型,包含三個欄位:name的文本欄位,是定時任務的名稱;numberOfUpdates的整型欄位,用於記錄任務調用次數;lastModified是時間類型,用於記錄任務的最後執行時間。

創建視圖

創建xml文件scheduler_demo.xml,內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<record model="ir.ui.view" id="view_scheduler_form">
<field name="name">scheduler.demo.form</field>
<field name="model">scheduler.demo</field>
<field name="arch" type="xml">
<form string="Schedule Form">
<group>
<field name="name"/>
<field name="numberOfUpdates"/>
<field name="lastModified"/>
</group>
</form>
</field>
</record>

<record model="ir.ui.view" id="view_scheduler_tree">
<field name="name">scheduler.demo.tree</field>
<field name="model">scheduler.demo</field>
<field name="arch" type="xml">
<tree string="Schedule Tree">
<field name="name"/>
<field name="numberOfUpdates"/>
<field name="lastModified"/>
</tree>
</field>
</record>
</data>
</odoo>

創建了兩個視圖,from視圖和tree視圖,方便我們查看記錄操作結果。這裡都是最基本的視圖定義寫法,沒有什麼特別需要說明的。

另外,我們需要讓視圖顯示出來,我這裡把菜單掛載在之前的開放學院菜單下,雖然這和開放學院沒什麼關聯。

<field name="lastModified"/>
</tree>
</field>
</record>

<record model="ir.actions.act_window" id="scheduler_demo_list_action">
<field name="name">計劃任務Demo</field>
<field name="res_model">scheduler.demo</field>
<field name="view_mode">tree,form</field>
</record>

<menuitem id="scheduler_demo_menu" name="計劃任務Demo"
parent="main_openacademy_menu"/>

<menuitem id="scheduler_demo_list_menu" name="計劃任務Demo"
parent="scheduler_demo_menu"
action="scheduler_demo_list_action"/>
</data>
</odoo>

這裡定義了一個菜單動作scheduler_demo_list_action,另外定義了兩級菜單。注意定義的順序,odoo對xml文件是順序載入的,意味著被引用的id一定要先定義。比如這裡必須先定義菜單動作,後定義菜單,因為菜單定義中會引用到菜單動作。

創建定時任務

接下來我們創建核心的定時任務,代碼還是寫在xml文件scheduler_demo.xml,我這裡放在了act_window定義之前。

<field name="lastModified"/>
</tree>
</field>
</record>

<record id="ir_cron_scheduler_demo_action" model="ir.cron">
<field name="name">Demo scheduler</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">2</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="scheduler.demo" name="model"/>
<field eval="process_demo_scheduler_queue" name="function"/>
</record>

<record model="ir.actions.act_window" id="scheduler_demo_list_action">
<field name="name">計劃任務Demo</field>

當你安裝模塊後,將添加一個定時任務:

Demo scheduler 定時任務界面


讓我們來分析下定時任務定義的代碼,這裡的ir.cron模塊就是odoo為所有定時任務而專門準備的模型。換句話說往這個表裡添加一行數據就是添加了一個定時任務。

name

定時任務名稱

user_id

執行定時任務的用戶,不同的用戶是有不同許可權的,為了保證能有足夠許可權執行定時任務,一般這裡就是base.user_root

interval_number

任務執行的頻次,和interval_type欄位一起決定了任務執行的間隔時間,比如這裡為interval_number為2,interval_type為minutes,就是任務每2分鐘執行一次。

interval_type

任務執行頻次的單位,可選項有: minutes,hours,days,work_days,weeks,months,意思很好理解,work_days是星期幾執行。

numbercall

循環運行的次數,比如你填10,那麼任務執行10次後將不再執行,這裡-1代表一直執行下去。

doall

如果在伺服器重啟期間錯過了執行時機,是否再次補充執行。

model

任務方法所在模塊

function

任務方法,與model一起決定了任務時機到來時,調用哪個方法執行。

添加python方法

是的,我們還有一個關鍵的地方,就是任務方法還沒有添加,在類文件scheduler_demo.py中添加代碼:

lastModified = fields.Datetime(Last updated)

def process_demo_scheduler_queue(self):
scheduler_line_ids = self.env[scheduler.demo].search([])
for scheduler_line in scheduler_line_ids:
_logger.info(line: + scheduler_line.name)
scheduler_line.numberOfUpdates += 1
scheduler_line.lastModified = datetime.utcnow()

這裡代碼很簡單,首先獲取scheduler.demo模型中的所有數據行,然後循環操作

  • _logger.info(line: + scheduler_line.name)在日誌輸出當前操作的數據行名稱
  • scheduler_line.numberOfUpdates += 1 將執行次數加1
  • scheduler_line.lastModified = datetime.utcnow() 更新最後執行時間。

結論

定時任務是Odoo中的一個強大工具,非常靈活的選項。利用好定時任務,可以幫我們節省大量的手工執行時間。


推薦閱讀:
相关文章