「Odoo 基礎教程系列」第六篇——從 Todo 應用開始(5)

Powered By @adigold1

你們好鴨,我又來更新啦!還記得咱們在第二篇教程中提到過的動做(actions)嗎,今天咱們就來專門講講在 Odoo 中的 action,學習不一樣類型的動做對應的應用場景,而且在咱們的 Todo 應用中使用上其中一些類型的動做。git

窗口動做

窗口動做在 Odoo 中是最多見也是最經常使用的動做類型,在第二篇教程中咱們建立菜單的時候就已經用過窗口動做了,咱們打開 menus.xml 來看看一個窗口動做的組成:github

<!-- menus.xml -->
    <record id="action_todo_task" model="ir.actions.act_window">
        <field name="name">待辦事項</field>
        <field name="res_model">todo.task</field>
        <field name="view_type">form</field>
        <field name="view_mode">tree,form</field>
        <field name="target">current</field>
    </record>

這裏的 model 以前咱們也說過,對應的是這個動做的類型(每一個類型的動做都對應一個模型),咱們重點來看看下面列出的字段以及沒有列出來的字段,分別說明一下它們各自的做用。web

  • res_model:要打開的視圖(窗口)關聯的數據模型
  • view_type:視圖類型,默認值爲 form,通常狀況下咱們取默認值就能夠了
  • view_mode:容許打開的視圖類型,以逗號分隔,默認值爲 tree,form
  • target:打開的窗口類型,經常使用的有 current(當前窗口打開)和 new (彈窗打開)這兩種,默認爲 current

除了上述列出的一些字段外,還有一些非必填的字段在某些時候咱們是會用上的,這裏也分列出來:瀏覽器

  • view_ids:關聯的視圖對象 id,需注意區分和 view_id 的區別
  • view_id:關聯的視圖的 id, 例如在不一樣時候須要打開同一個數據模型不一樣的表單視圖,就能夠經過這個字段指定要打開的視圖的 id
  • res_id:僅在視圖類型爲 form 時有效,表示打開該 id 對應的記錄的表單視圖,如未指定則打開新建頁面
  • context:傳遞到上下文中的數據,一個字典
  • domain:過濾規則,對視圖中的記錄進行過濾
  • limit:列表中每頁顯示的記錄數量,默認爲 80
  • search_view_id:指定搜索視圖,不指定則按默認規則加載
  • multi:若是設置爲 True 且動做綁定了模型(src_model)的話,該動做按鈕會只出如今所綁定模型列表視圖的「動做」下拉列表中(在搜索視圖左側)
  • views:由 (view_id, view_type) 這樣的元組對組成的列表,view_id 爲指定視圖的 id 或是 False(按默認值取出對應視圖),view_type 表示視圖類型

其中 views 是一個計算字段,該字段會根據 view_ids, view_modeview_id 自動計算出來,大體分爲三個步驟:服務器

  1. view_ids 中順序取出 id 和視圖類型,組成 (view_id, view_type) 元組對加入到 views 列表中
  2. 若定義了 view_id 且對應的視圖類型不在 view_ids 中,則加入到 views
  3. 最後對 view_mode 中指定的視圖類型,可是不存在於 view_idsview_id 中,則將其 view_id 置爲 False 組成元組對後加入到 views

這裏須要強調一點的是,若是咱們在某些時候須要直接經過 Python 代碼或 JS 代碼打開一個窗口動做,此時咱們將須要本身添加 views 字段,不然將會拋出錯誤,具體的實例咱們將在以後使用到了再進行講解分析。框架

服務器動做

Server Action 能夠在服務端執行復雜的邏輯代碼,是很是強大的一種動做類型。咱們先給代辦事項添加一個 Server Action 用於快速完成任務的動做,這樣咱們就不用每次都要點進去一個任務而後進入編輯狀態再勾選保存這麼多步驟了。dom

咱們來看看定義一個最簡單的 Server Action 應該包含哪些內容:學習

<!-- views.xml -->
    <record id="action_mark_todo_task_done" model="ir.actions.server">
        <field name="name">標記完成</field>
        <field name="model_id" ref="model_todo_task"/>
        <field name="binding_model_id" ref="model_todo_task"/>
        <field name="state">code</field>
        <field name="code">records.write({'is_done': True})</field>
    </record>

和其餘全部在數據文件(XML)中定義的數據同樣,首先是一個包含屬性 idmodel<record /> 標籤,咱們要定義的是 Server Action, 因此須要將 model 設置爲 ir.actions.server,而後是對應 Server Action 模型下的一些字段:google

  • model_id:當前的動做是在哪一個模型上運行的
  • binding_model_id:綁定的模型,當前動做將會出如今綁定的模型的視圖中
  • state:服務器動做的類型,總共有 4 種可選的類型,分別是 code(執行 Python 代碼),object_create(建立一條新記錄),object_write(更新記錄),multi(執行多個動做)
  • code:對應 state 的類型 code,爲當前動做運行時所要執行的 Python 代碼

你們應該都留意到了在上面的定義中出現了一個屬性 ref,若是我沒有理解錯,它應該是 reference 的縮寫,它的值是一個外部 ID(external id),咱們上面定義的這個動做的外部 ID 就是定義時添加的 id 屬性的值 action_mark_todo_task_done,它指向一條具體的記錄(就像 Many2one 字段同樣)。url

咱們定義的全部模型都會在 ir.model.data 對應的表中存在相應的記錄,這些模型的外部 ID 形如 model_model_name,其中 model_name 是將模型名 [model.name](http://model.name). 替換成 _,例如咱們的 todo.task 模型的外部 ID 就是前綴 model_ 加上 todo_task 組成的 model_todo_task 了。

接下來咱們再看到字段 code 裏面的內容,在這裏面咱們有一些變量是能夠直接使用的:

  • env:Odoo 的運行環境
  • model:動做觸發時對應的 Odoo 模型實例
  • record:動做觸發時對應的單個記錄(如在表單視圖中運行對應當前表單所指向的記錄),多是空的
  • records:動做觸發時對應的記錄集(如在列表視圖中勾選多條記錄觸發,記錄集指向這些選中的記錄),多是空的
  • Python 庫:time, datetime, dateutil, timezone 時間相關的 Python 庫
  • log:用來記錄日誌信息
  • Warning:經過 raise Warning('xxxxx') 拋出警告信息

除了上述能夠直接使用的變量外,還有一個 action 變量,當咱們想讓當前動做執行完畢以後,返回一個新的動做繼續執行,就能夠將返回的動做的定義(一個字典)賦值給變量 action,客戶端將會自動執行該動做。

OK, 前面說了這麼多,咱們更新一下代碼,而後刷新瀏覽器看看效果吧:

Server Action

在列表視圖中,當咱們勾選了任意的記錄後,將會出現一個「動做」菜單,打開以後就能夠看到咱們剛剛定義的「標記完成」這個 Server Action 了,試試看執行會發生什麼,注意觀察「已完成?」這一列的變化。而後再建立一條新的記錄,在表單頁面中,一樣有「動做」菜單,咱們在這裏也能夠執行「標記完成」的動做,怎麼樣,是否是比本來的編輯再勾選再保存要方便得多了,並且咱們還能在列表裏勾選多條記錄進行批量操做,不能更方便了!

受限於篇幅,咱們這裏只涉及了 statecode 類型的服務器動做,相對其餘三種類型,已經足以應付絕大多數場景的需求了,這裏就不展開細說,感興趣的同窗能夠看看官方模塊的相關實現,要學會看源碼哈!

URL 動做

URL Action 用來打開一個網頁連接,十分簡單的一種動做類型:

<record id="action_open_google" model="ir.actions.act_url">
        <field name="name">打開谷歌</field>
        <field name="target">new</field>
        <field name="url">https://google.com</field>
    </record>

上面這個動做觸發後將會新開瀏覽器窗口(或新標籤)打開谷歌首頁,主要的兩個字段以下:

  • target:有兩個可選值,分別是新窗口(new)打開連接,至關於 <a target='_blank' />,以及當前窗口(self)打開,至關於 <a target='_self' />
  • url:要打開的目標頁面的連接,能夠是外部頁面也能夠是同域下的內部頁面

客戶端動做

觸發一個徹底由客戶端(瀏覽器)執行的動做,例如某些模塊的「儀表板」就屬於 Client Action,它的基本組成以下:

<record id="backend_dashboard" model="ir.actions.client">
        <field name="name">Dashboard</field>
        <field name="tag">backend_dashboard</field>
    </record>

上面這個 Client Action 是在 Odoo 自帶模塊 website 中定義,用來打開儀表板,來看看客戶端動做有哪些字段是可用的:

  • tag:客戶端動做的標識,須要是在 action_registry 中註冊了的動做
  • target:同學口動做
  • context:同學口動做
  • params:傳遞給客戶端動做的參數,一個字典

客戶端動做的本體其實是 tag 所指向的動做,這個動做是用 JS 編寫的一些邏輯(在 Odoo 的 JS 框架下),在以後會有專門的教程教你們相關的內容,這裏請先略過。

報表動做

這類型的動做用於觸發報表打印,例如打印發票等。這裏不對該類型做介紹,感興趣的同窗一樣能夠去看看 Odoo 自帶的一些模塊如 account 等。

瞎說幾句

在實際開發中,最常接觸和使用的動做基本上就窗口動做(ir.actions.act_window)和服務器動做(ir.actions.server)這兩種了,其中 Server Action 最複雜也最強大,能夠用它來實現不少的功能。

上面沒有展開細說的內容,但願你們能夠多多翻看官方模塊的實現,學會閱讀源碼纔是最好的學習方式。

教程中的代碼會更新在 GitHub 倉庫「Odoo-Tutorial-Demo」中,若是遇到什麼問題,歡迎提出,我會及時解答 ;-)

相關文章
相關標籤/搜索