[精]Odoo 8.0深入浅出开发教程-模块开发基础
參考資料點擊這里.
構建Odoo模塊
模塊組成
業務對象
業務對象聲明為Python類, 由Odoo自己主動加載.
數據文件
XML或CSV文件格式, 在當中聲明了元數據(視圖或工作流)、配置數據(模塊參數)、演示數據等.
Web控制器
處理Web瀏覽器發來的requests.
靜態web數據
Web用到的圖像, CSS或JavaScript文件.
模塊結構
一個Odoo模塊也是一個Python模塊, 存放在一個文件夾中, 包括一個__init__.py文件, 用于導入其它Python模塊.
from . import mymodule
odoo.py提供了一個子命令scaffold能夠方便地創建一個空的模塊.
$ odoo.py scaffold <module name> <where to put it>
命令運行后, 將會創建一個子文件夾而且當中包括了Odoo模塊所需的一些基本文件.
練習 #1
運行 ./odoo.py scaffold openacademy addons, 在addons文件夾下創建一個名為openacademy的模塊, 生成的文件夾文件結構例如以下.
openacademy
├── __init__.py
├── __openerp__.py
├── controllers.py
├── demo.xml
├── models.py
├── security
│ └── ir.model.access.csv
└── templates.xml
各文件內容請查看文件或查看原文, 然后對__openerp__.py中的幾種標識文本進行改動.
對象關系映射
ORM層是Odoo的一個關鍵組件, 它能夠避免大部分的SQL語句編寫從而提高擴展性和安全性.
業務對象用派生自Model的Python類(模型)來編寫, 該類的_name屬性定義了模型在Odoo系統中的名稱.
from openerp import models
class MinimalModel(models.Model):_name = 'test.model'
字段
字段定義模型能夠存儲什么以及在哪里存儲, 字段在模型類中用屬性來定義.
from openerp import models, fieldsclass LessMinimalModel(models.Model):_name = 'test.model2'name = fields.Char()
通用屬性
與模型相似, 字段也能夠通過參數傳遞對其進行設定:
name = field.Char(required=True)
字段的經常使用屬性有:
string (unicode, default: field’s name)
The label of the field in UI (visible by users).
required (bool, default: False)
If True, the field can not be empty, it must either have a default value or always be given a value when creating a record.
help (unicode, default: ‘’)
Long-form, provides a help tooltip to users in the UI.
index (bool, default: False)
Requests that Odoo create a database index on the column
簡單字段
字段能夠分為兩類: 簡單字段和關系字段. 前者為原子值, 直接保存在模型相應的數據庫表中; 后者連接到其它的記錄上(能夠是同樣的模型也能夠是不同的模型).
Boolean, Date, Char這些都是簡單字段.
保留字段
Odoo在模型中自己主動創建并維護一些字段, 這些字段就是保留字段, 這些字段數據不須要也不應該手動去改動.
id (Id)
the unique identifier for a record in its model
create_date (Datetime)
creation date of the record
create_uid (Many2one)
user who created the record
write_date (Datetime)
last modification date of the record
write_uid (Many2one)
user who last modified the record
特殊字段
默認情況下, Odoo要求模型中有一個name字段, 用于顯示和搜索, 通過設置_rec_name也能夠達到這種目的.
練習 #2
在openacademy模塊中定義一個新的模型Course, openacademy/models.py內容例如以下:
# -*- coding: utf-8 -*-
from openerp import models, fields, api
class Course(models.Model):_name = 'openacademy.course'name = fields.Char(string="Title", required=True)description = fields.Text()
數據文件
Odoo是一個高度數據驅動的系統, 盡管使用Python代碼來定制模塊行為, 但非常多模塊數據是在其加載時setup的, 而且有些模塊僅僅為Odoo加入數據.
通過數據文件來定義模塊數據, 比如能夠使用XML文件里的<record>元素定義數據, 每個<record>元素創建或者更新數據庫中的一條記錄, 形式例如以下:
<openerp><data><record model="{model name}" id="{record identifier}"><field name="{a field name}">{a value}</field></record></data>
<openerp>
model
Odoo模型名.
id
外部ID(External Identifier), 通過它能夠引用到記錄(而且不須要知道記錄所在的數據庫ID).
元素
name屬性用于確定字段名稱(比如description), 該元素的body給出字段的值.
數據文件必須在模塊加載清單文件列表中, 也就是__openerp__.py的’data’列表(所有加載)或’demo’列表(僅僅有設定為加載演示數據才會加載)中.
練習 #3
創建一個數據文件來向Course中加入數據, 編輯openacademy/demo.xml, 并確認__openerp__.py的’demo’列表中有該文件.
<openerp><data><record model="openacademy.course" id="course0"><field name="name">Course 0</field><field name="description">Course 0's descriptionCan have multiple lines</field></record><record model="openacademy.course" id="course1"><field name="name">Course 1</field><!-- no description for this one --></record><record model="openacademy.course" id="course2"><field name="name">Course 2</field><field name="description">Course 2's description</field></record></data>
</openerp>
動作和菜單
在Odoo中, 動作和菜單都是定義在數據庫中的數據記錄, 一般通過數據文件來定義.
動作能夠由三種方式觸發:
- 點擊菜單項(菜單項鏈接到特定動作)
- 點擊視圖上的按鈕(假設按鈕連接到動作)
- 作為對象的上下文動作
使用<menuitem>聲明一個ir.ui.menu并將其連接到一個action, 能夠用以下的形式的代碼.
<record model="ir.actions.act_window" id="action_list_ideas"><field name="name">Ideas</field><field name="res_model">idea.idea</field><field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_ideas" parent="menu_root" name="Ideas" sequence="10"action="action_list_ideas"/>
注意: action必須先于menu的連接使用定義, 數據文件在加載時順序地運行, 所以動作的ID必須首先存在于數據庫中才干使用.
練習 #4
定義一個新的菜單項訪問OpenAcademy課程.
創建openacademy/views/openacademy.xml文件, 并在當中加入動作和菜單.
<?xml version="1.0" encoding="UTF-8"?
>
<openerp> <data> <!-- window action --> <!-- The following tag is an action definition for a "window action", that is an action opening a view or a set of views --> <record model="ir.actions.act_window" id="course_list_action"> <field name="name">Courses</field> <field name="res_model">openacademy.course</field> <field name="view_type">form</field> <field name="view_mode">tree,form</field> <field name="help" type="html"> <p class="oe_view_nocontent_create">Create the first course </p> </field> </record> <!-- top level menu: no parent --> <menuitem id="main_openacademy_menu" name="Open Academy"/> <!-- A first level in the left side menu is needed before using action= attribute --> <menuitem id="openacademy_menu" name="Open Academy" parent="main_openacademy_menu"/> <!-- the following menuitem should appear *after* its parent openacademy_menu and *after* its action course_list_action --> <menuitem id="courses_menu" name="Courses" parent="openacademy_menu" action="course_list_action"/> <!-- Full id location: action="openacademy.course_list_action" It is not required when it is the same module --> </data> </openerp> 在__openerp__.py中加入這個數據文件名稱到’data’.
'data': [# 'security/ir.model.access.csv','templates.xml','views/openacademy.xml',],
更新模塊后能夠看到菜單, 操作看看效果.
基本視圖
視圖定義了模型數據怎樣顯示, 每種類型的視圖代表一種數據可視化模式.
主要的視圖定義
一個視圖是以一條ir.ui.view模型數據的形式定義的.
<record model="ir.ui.view" id="view_id"><field name="name">view.name</field><field name="model">object_name</field><field name="priority" eval="16"/><field name="arch" type="xml"><!-- view content: <form>, <tree>, <graph>, ... --></field>
</record>
Tree views
Tree view也被稱為list views, 在一個表格中顯示記錄. 根元素是<tree>, 最簡形式的tree view僅僅是簡單地列出每條記錄的多個字段, 每個字段為一列.
<tree string="Idea list"><field name="name"/><field name="inventor_id"/>
</tree>
Form views
Form用于創建或編輯單條記錄, 根元素是<form>, 能夠在form中組合各種高層結構元素(如groups, notebooks)以及交互元素(如buttons, fields).
<form string="Idea form"><group colspan="4"><group colspan="2" col="2"><separator string="General stuff" colspan="2"/><field name="name"/><field name="inventor_id"/></group><group colspan="2" col="2"><separator string="Dates" colspan="2"/><field name="active"/><field name="invent_date" readonly="1"/></group><notebook colspan="4"><page string="Description"><field name="description" nolabel="1"/></page></notebook><field name="state"/></group>
</form>
練習 #5
為openacademy創建form view, views/openacademy.xml數據文件里添加<record model=”ir.ui.view”…>內容.
<?xml version="1.0" encoding="UTF-8"?>
<openerp><data><record model="ir.ui.view" id="course_form_view"><field name="name">course.form</field><field name="model">openacademy.course</field><field name="arch" type="xml"><form string="Course Form"><sheet><group><field name="name"/><field name="description"/></group></sheet></form></field></record><!-- window action --><!--The following tag is an action definition for a "window action",
更新模塊, 創建一個Course, 能夠看到form view變了.
練習 #6
使用notebook. 在form view中, 將description字段放在一個tab中, 方便隨后加入其它tabs, 對練習#5的form view數據做例如以下改動.
<sheet><group><field name="name"/></group><notebook><page string="Description"><field name="description"/></page><page string="About">This is an example of notebooks</page></notebook></sheet></form>
</field>
更新模塊, 看效果.
More
還能夠使用HTML為form view提供更加靈活的布局, 比如以下的樣例.
<form string="Idea Form"><header><button string="Confirm" type="object" name="action_confirm"states="draft" class="oe_highlight" /><button string="Mark as done" type="object" name="action_done"states="confirmed" class="oe_highlight"/><button string="Reset to draft" type="object" name="action_draft"states="confirmed,done" /><field name="state" widget="statusbar"/></header><sheet><div class="oe_title"><label for="name" class="oe_edit_only" string="Idea Name" /><h1><field name="name" /></h1></div><separator string="General" colspan="2" /><group colspan="2" col="2"><field name="description" placeholder="Idea description..." /></group></sheet>
</form>
Search views
Search views用來自己定義list views及其它統計/多條記錄視圖中的搜索字段. 根元素為<search>, 其子元素定義了在哪些字段上進行搜索.
<search><field name="name"/><field name="inventor_id"/>
</search>
假設一個模型未定義相應的Search view, odoo自己主動創建一個僅搜索name字段的search view.
練習 #7
加入title以及description搜索, 在views/openacademy.xml中定義search view.
</field>
</record><record model="ir.ui.view" id="course_search_view"><field name="name">course.search</field><field name="model">openacademy.course</field><field name="arch" type="xml"><search><field name="name"/><field name="description"/></search></field>
</record><!-- window action -->
<!--The following tag is an action definition for a "window action",
更新模塊, 搜索框輸入字符后能夠看到下方能夠選擇搜索description字段.
模型中的關聯
概述
一個模型中的記錄可能關聯到其它模型的記錄, 比如銷售訂單記錄會關聯到一個包括客戶信息的客戶記錄.
練習 #8
為了說明數據關聯, 首先添加新的模型.
Open Academy模塊中, 一個session是一個在特定時間針對特定聽眾講授課程的過程. 須要為session創建相應的模型.
session具有name, 開始日期, 持續時間以及座位數量等. 此外還須要加入相應的action和menuitem顯示模型數據.
首先在openacademy/models.py中創建Session類.
class Session(models.Model):_name = 'openacademy.session'name = fields.Char(required=True)start_date = fields.Date()duration = fields.Float(digits=(6, 2), help="Duration in days")seats = fields.Integer(string="Number of seats")
然后在openacademy/view/openacademy.xml中加入用于訪問session模型的action和menuitem定義.
<!-- Full id location:action="openacademy.course_list_action"It is not required when it is the same module --><!-- session form view --><record model="ir.ui.view" id="session_form_view"><field name="name">session.form</field><field name="model">openacademy.session</field><field name="arch" type="xml"><form string="Session Form"><sheet><group><field name="name"/><field name="start_date"/><field name="duration"/><field name="seats"/></group></sheet></form></field></record><record model="ir.actions.act_window" id="session_list_action"><field name="name">Sessions</field><field name="res_model">openacademy.session</field><field name="view_type">form</field><field name="view_mode">tree,form</field></record><menuitem id="session_menu" name="Sessions"parent="openacademy_menu"action="session_list_action"/></data>
</openerp>
digits=(6,2)確定浮點數的精度, 6表示總的數字位數(不包括小數點), 2表示小數點后的位數. 所以, digits=(6,2)小數點前最多4位.
轉載于:https://www.cnblogs.com/wzzkaifa/p/7338602.html
總結
以上是生活随笔為你收集整理的[精]Odoo 8.0深入浅出开发教程-模块开发基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 去清东陵不买门票可以吗
- 下一篇: 优优面膜多少钱一盒?