在這篇教程裏咱們將會了解到 Odoo 模型裏的一些其餘類型的字段和特殊機制,而我依然會繼續帶領你們一塊兒完善咱們的 Todo 應用,不斷地往裏面添加一些新的功能特性,讓它看起來更豐滿也更實用一些。python
在上一篇教程中,咱們已經建立好了待辦事項的模型,可是隻是添加了「描述」和「已完成?」兩個字段,這確定是不能知足咱們的需求的。如今咱們來給待辦事項增長一個「緊急程度」的字段,用來表示當前任務的優先級。git
# models.py class TodoTask(models.Model): _name = 'todo.task' _description = '待辦事項' name = fields.Char('描述', required=True) is_done = fields.Boolean('已完成?') priority = fields.Selection([ ('todo', '待辦'), ('normal', '普通'), ('urgency', '緊急') ], default='todo', string='緊急程度')
咱們添加了一個 Selection
類型的字段 priority
,而且指定了三個可供選擇的程度類型,通常狀況下,若是一個字段只有固定的幾種可選值,一般都會選擇使用 Selection
字段,它接受一個元組列表做爲參數,其中元組的組成爲 (value, string)
,左邊的是數據庫中存儲的值,右邊的是一個用於界面顯示的描述。github
此處咱們還給這個字段添加了默認值 todo
,表示當一個待辦事項被建立後,若是沒有指定緊急程度,將默認是待辦狀態。咱們能夠爲任意類型的字段添加默認值。shell
在上一篇教程中咱們提到過,在對模型進行改動以後,須要對模塊進行升級才能看到變動後的樣子,除了從應用列表中找到模塊進行升級外,咱們還能夠在命令行中給 Odoo 的啓動命令加上參數 -u todo
指定升級 todo 模塊。數據庫
./odoo-bin --addons-path=addons,../mymodules --db-filter=^demo$ -d demo -u todo
升級後建立或打開任意一條待辦事項進入到表單頁面,就能夠看到已經多了「緊急程度」這個字段了,而且默認選擇了「待辦」這一狀態。小程序
咱們已經給待辦事項加上緊急程度了,但是光有這個還不夠,咱們還要給它加上截止時間,畢竟 deadline 是第一輩子產力呀!api
# models.py deadline = fields.Datetime(u'截止時間')
咱們把截止日期也放到 TreeView 中,方便查看各個任務的 deadline微信
<!-- views.xml --> <field name="arch" type="xml"> <tree string="Todo"> <field name="name"/> <field name="deadline"/> <field name="is_done"/> </tree> </field>
不少時候咱們會須要用不一樣的顏色對待辦事項進行標記,例如咱們會但願已通過期的任務以紅色標記來提醒咱們,這個任務過時了。任務是否已通過期,咱們要先知道任務的截止時間(上面一小節已經加上了)和當前時間,而後進行比較判斷任務的截止時間是否小於當前時間,若是是則表示任務已通過期了,咱們須要在視圖上用紅色將對應的任務標記起來。那將這個需求轉化成代碼應該怎麼作呢?ui
這個需求跟時間有關,而且時間是流動(一直在變化)的,因此咱們應該要有一個方法在用戶每次打開待辦事項以前,把這個結果計算好,而且反饋給用戶,還好 Odoo 的 ORM 已經爲咱們實現了相關的機制——計算字段(Computed fields
)spa
# models.py is_expired = fields.Boolean(u'已過時', compute='_compute_is_expired') @api.depends('deadline') @api.multi def _compute_is_expired(self): for record in self: if record.deadline: record.is_expired = record.deadline < fields.Datetime.now() else: record.is_expired = False
計算字段其實和其餘字段同樣,只不過多了一個 compute
屬性,它的值是計算這個字段值的方法名。咱們來看一下對應的方法 _compute_is_expired
頭頂上的 @api.depends
這個裝飾器,它接受了一個參數 deadline
,表示的是 is_expired
這個字段的計算會用到 deadline
這個字段的值(咱們須要用它的值和當前時間進行比較),若是一個計算字段會用到多個其餘字段的值,這裏就須要以逗號分隔,將用到的值的字段名依次傳入裝飾器中。
而 @api.multi
則表示該方法中的 self
是一個記錄集(多個實例的集合),若是不理解,能夠暫時不深究,到後面天然會知道這裏的實際用法。
再來看看實際的計算邏輯部分,只有一個循環以及一條賦值語句,剛剛已經提到過這裏的 self
表示一個記錄集,咱們須要對這個記錄集裏的每一條記錄進行計算,判斷這個待辦事項是否已通過期,這裏的 record
就是每一條記錄的實例對象,咱們用這條記錄的 deadline
的值和當前時間 fields.Datetime.now()
進行比較,而後將結果賦值給字段 is_expired
,就是這麼簡單。
PS: 這裏咱們對 deadline
進行了判斷,是由於若是沒有設置截止時間,又或者是在新建代辦事項時,這裏的 deadline
會是一個布爾值,是不能和時間字符串進行比較的。
其中你們可能會有疑問的應該是當前時間的獲取,爲何不是用 datetime.now()
吧?實際上獲取當前時間用的也是這個方法,只不過 Odoo 的 ORM 替咱們封裝了一層,fields.Datetime.now()
是類 Datetime
的靜態方法:
# fields.py class Datetime(Field): type = 'datetime' column_type = ('timestamp', 'timestamp') column_cast_from = ('date',) @staticmethod def now(*args): """ Return the current day and time in the format expected by the ORM. This function may be used to compute default values. """ return datetime.now().strftime(DATETIME_FORMAT)
好的,這裏先不過多糾結細節問題,如今咱們已經能夠計算出來每一個待辦事項是否已通過期了,那要怎麼去用這個計算字段呢?咱們打開視圖文件來加點東西上去:
<!-- views.xml --> <field name="arch" type="xml"> <tree string="Todo" decoration-danger="is_expired"> <field name="name"/> <field name="deadline"/> <field name="is_done"/> <field name="is_expired" invisible="True"/> </tree> </field>
在視圖中咱們把 is_expired
字段加了進去,而且還加上了屬性 invisible
,這個屬性的做用是將當前字段隱藏起來,由於這裏咱們不但願用戶看到這個字段的值,而是將結果反映在顏色上。而後咱們再看到 <tree />
標籤多了一個屬性 decoration-danger
,這個屬性能夠接受表達式或字段名做爲值,當結果爲真時,這個屬性就會生效,將 TreeView 中知足表達式的行以紅色標記,實際的效果以下:
今天這篇教程的內容就先到這裏了,下一篇再繼續帶你們深刻更多的內容。這篇教程中的代碼一樣會更新在個人 GitHub
倉庫中。
倉庫地址:Odoo-Tutorial-Demo
距離上一次更新,已通過了好幾個月了,這段時間除了忙公司的事情,還額外在作一些別的東西,而後最近在開發一個小程序。一直很想抽空出來更新這個系列的教程,一邊又有不少事情在忙,拖更了實在是抱歉了!
若是你有任何的疑問,歡迎留言,我將會盡快給出答覆,若是想要加羣或者加好友,能夠發送站內信給我,我會回覆你微信號~
期待下一篇教程能夠繼續和大家見面。