<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                > 警告 > 本教程需要已經安裝odoo [TOC] #### 啟動/停止Odoo服務器 Odoo采用C/S架構,客戶端通過Web瀏覽器訪問服務端,遵從RPC協議。業務邏輯和擴展通常在服務端執行,而只有添加客戶端支持的新特征才會在客戶端添加代碼(例如,交互過程中新數據的映射表示)。啟動服務器,只需要在shell中調用命令odoo-bin,或者完整的路徑名調用: ~~~ odoo-bin ~~~ 通過`Ctrl-c`或殺死相應的系統進程來停止Odoo服務。 #### 構建一個Odoo模塊 服務端擴展和客戶端擴展都被封裝為模塊,這些模塊可選擇性的被安裝,安裝完成后通過數據庫來加載。模塊即可以是全新的業務邏輯,也可以是更改和擴展已有的業務邏輯。比如創建一個中國會計模塊,將中國的會計準則添加到Odoo的通用會計中,也可以創建一個全新的實時可視化管理車隊的模塊。Odoo中的所有功能都是包含在模塊中。 ##### 模塊的組成 Odoo模塊包含多個部分: **業務對象**   Python類,這些類會被Odoo框架自動持久化,持久化的方式決定于類的定義。 **數據文件**   包括視圖、菜單、動作、工作流、權限、演示數據等,以XML或CSV文件定義。 **Web控制器**   處理Web瀏覽器的請求 **靜態頁面數據**   網站或界面使用的圖片、CSS或JavaScript文件 ##### 模塊結構 每個模塊都是模塊目錄中的一個子目錄。可以通過`--addons-path`選項指定模塊目錄的路徑。 > 提示 > 大多數命令行選項可以通過配置文件進行設置 Odoo模塊由清單文件進行聲明。查看清單文件文檔了解詳細信息。模塊是一個包含`__init__.py`文件的的Python包,`__init__.py`文件包含了模塊需要的導入的各Python文件。 例如,如果模塊中包含`mymodule.py`文件,`__init__.py`應該這樣寫: ~~~ from . import mymodule ~~~ Odoo提供了腳手架機制來快速創建新模塊,`odoo-bin`子命令`scaffold`用來創建一個空模塊 ~~~ $ odoo-bin scaffold <模塊名> <模塊放置路徑> ~~~ 該命令為模塊創建一個子目錄,并自動為模塊創建一些標準文件。這些文件大多只包含被注釋的代碼和XML元素。后面將解釋這些文件的含義。 > **練習創建模塊** > 使用上面的命令行創建一個空模塊*Open Academy*,并將其安裝在Odoo中。 > > 1. 調用命令`odoo-bin scaffold openacademy addons` > 2. 修改模塊中的相關文件 > 3. 不要修改其它文件 `openacademy/__manifest__.py` ~~~ # -*- coding: utf-8 -*- { 'name': "Open Academy", 'summary': """Manage trainings""", 'description': """ Open Academy module for managing trainings: - training courses - training sessions - attendees registration """, 'author': "My Company", 'website': "http://www.yourcompany.com", # Categories can be used to filter modules in modules listing # Check https://github.com/odoo/odoo/blob/master/odoo/addons/base/module/module_data.xml # for the full list 'category': 'Test', 'version': '0.1', # any module necessary for this one to work correctly 'depends': ['base'], # always loaded 'data': [ # 'security/ir.model.access.csv', 'templates.xml', ], # only loaded in demonstration mode 'demo': [ 'demo.xml', ], } ~~~ `openacademy/__init__.py` ~~~ # -*- coding: utf-8 -*- from . import controllers from . import models ~~~ `openacademy/controllers.py` ~~~ # -*- coding: utf-8 -*- from odoo import http # class Openacademy(http.Controller): # @http.route('/openacademy/openacademy/', auth='public') # def index(self, **kw): # return "Hello, world" # @http.route('/openacademy/openacademy/objects/', auth='public') # def list(self, **kw): # return http.request.render('openacademy.listing', { # 'root': '/openacademy/openacademy', # 'objects': http.request.env['openacademy.openacademy'].search([]), # }) # @http.route('/openacademy/openacademy/objects/<model("openacademy.openacademy"):obj>/', auth='public') # def object(self, obj, **kw): # return http.request.render('openacademy.object', { # 'object': obj # }) ~~~ `openacademy/demo.xml` ~~~ <odoo> <data> <!-- --> <!-- <record id="object0" model="openacademy.openacademy"> --> <!-- <field name="name">Object 0</field> --> <!-- </record> --> <!-- --> <!-- <record id="object1" model="openacademy.openacademy"> --> <!-- <field name="name">Object 1</field> --> <!-- </record> --> <!-- --> <!-- <record id="object2" model="openacademy.openacademy"> --> <!-- <field name="name">Object 2</field> --> <!-- </record> --> <!-- --> <!-- <record id="object3" model="openacademy.openacademy"> --> <!-- <field name="name">Object 3</field> --> <!-- </record> --> <!-- --> <!-- <record id="object4" model="openacademy.openacademy"> --> <!-- <field name="name">Object 4</field> --> <!-- </record> --> <!-- --> </data> </odoo> ~~~ `openacademy/models.py` ~~~ # -*- coding: utf-8 -*- from odoo import models, fields, api # class openacademy(models.Model): # _name = 'openacademy.openacademy' # name = fields.Char() ~~~ `openacademy/security/ir.model.access.csv` ~~~ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink access_openacademy_openacademy,openacademy.openacademy,model_openacademy_openacademy,,1,0,0,0 ~~~ `openacademy/templates.xml` ~~~ <odoo> <data> <!-- <template id="listing"> --> <!-- <ul> --> <!-- <li t-foreach="objects" t-as="object"> --> <!-- <a t-attf-href="{{ root }}/objects/{{ object.id }}"> --> <!-- <t t-esc="object.display_name"/> --> <!-- </a> --> <!-- </li> --> <!-- </ul> --> <!-- </template> --> <!-- <template id="object"> --> <!-- <h1><t t-esc="object.display_name"/></h1> --> <!-- <dl> --> <!-- <t t-foreach="object._fields" t-as="field"> --> <!-- <dt><t t-esc="field"/></dt> --> <!-- <dd><t t-esc="object[field]"/></dd> --> <!-- </t> --> <!-- </dl> --> <!-- </template> --> </data> </odoo> ~~~ #### 對象關系映射 Odoo的關鍵組件是ORM層。這個層避免了大量手寫SQL,并提供擴展性和安全性。業務對象被聲明為`Model`類的擴展類,并自動將它們集成到持久層中。可以通過定義時設置屬性來配置模型。最重要的屬性是`_name`,必填屬性,它定義了模塊在Odoo系統中的名稱。一個最簡單的模型定義: ~~~ from odoo import models class MinimalModel(models.Model): _name = 'test.model' ~~~ #### 模型字段 字段定義了模型中需要存儲的內容和存儲的位置。字段通過類的屬性來定義: ~~~ from odoo import models, fields class LessMinimalModel(models.Model): _name = 'test.model2' name = fields.Char() ~~~ **通用屬性** 和模型一樣,字段也可以配置,字段通過屬性參數的方式來配置: ~~~ name = field.Char(required=True) ~~~ 一些屬性可以用于所有字段,以下是最常見的屬性: `string(unicode,default: field's name)`   用戶界面中的字段標簽(用戶可見) `required(bool,default:False)`   如果為True,這個字段不能為空,它必須有一個默認值或者在創建記錄時總是給定一個值。 `help (unicode, default: '')`   長格式,在用戶界面上顯示的提示。 `index (bool, default: False)`   請求Odoo在列上創建數據庫索引。 **簡單字段** 有兩大類字段:簡單字段和關聯字段,簡單字段的值是存儲在模型表中的原子值,而關聯字段是指向模型(相同模型或不同模型)的記錄行。 簡單字段的例子如:Boolean、Date、Char 關聯字段的例子如:Many2One、One2Many、Many2Many **保留字段** Odoo在所有模型中都創建幾個固定字段,這些字段由系統管理,用戶程序不應寫入。但是可以在用戶程序中讀取: `id(Id)`   模型中記錄的唯一標識符 `create_date(Datetime)`   記錄的創建日期 `create_uid(Many2one)`   創建記錄的用戶 `write_date(Datetime)`   記錄的最后修改時間 `write_uid(Many2one)`   上次修改記錄的用戶 **特殊字段** 默認情況下,Odoo的name在所有模型上還需要一個字段,用于顯示和搜索。用于這些目的的字段可以通過設置字段`_rec_name`來實現。 > 練習定義模型,在openacademy模塊中定義新的數據模型*課程*,每門課程包含兩個字段,標題和描述,其中標題是必填字段。編輯文件`openacademy/models/models.py`以包含`Course`類。 `openacademy/models.py` ~~~ from odoo import models, fields, api class Course(models.Model): _name = 'openacademy.course' name = fields.Char(string="Title", required=True) description = fields.Text() ~~~ #### 數據文件 Odoo是一個高度數據驅動的系統,雖然行為是通過Python代碼制定的,但一些模塊的值是在加載時通過數據文件設置的。 > 提示: > 一些模塊的作用僅僅是為了將數據添加到Odoo中 模塊數據通過帶有`<record>`元素的XML數據文件來聲明。每個`<record>`元素創建或更新數據庫中的一個記錄行。 ~~~ <odoo> <data> <record model="{model name}" id="{record identifier}"> <field name="{a field name}">{a value}</field> </record> </data> </odoo> ~~~ * `model`是在記錄行中記錄的Odoo模型名稱 * `id`是外部標識符,它允許引用記錄(而不必知道其在數據庫中的標識符) * `<field>`,每個`<field>`對應數據行中的一個字段,name屬性是字段名(例如*description*),而`body`就是字段的值。 數據文件通過在manifest文件聲明而被載入,他們既可以在`data`列表聲明(始終載入)也可以在`demo`列表聲明(僅在演示模式下載入) > 練習定義演示數據,添加演示數據以填充*Course*模型的數據,編輯文件`openacademy/demo/demo.xml`來添加演示數據 `openacademy/demo/demo.xml` ~~~ <odoo> <data> <record model="openacademy.course" id="course0"> <field name="name">Course 0</field> <field name="description">Course 0's description Can 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> </odoo> ~~~ #### 操作和菜單 操作和菜單是數據庫中的常規數據,通常以數據文件聲明。操作可以通過三種方式觸發: 1.點擊菜單項(鏈接到特定操作) 2.點擊視圖中的按鈕(如果這些按鈕已經被連接到操作) 3.作為對象的上下文操作 因為菜單的聲明相對復雜,所以有個一個`<menuitem>`的快捷方式來聲明`ir.ui.menu`菜單對象,并將其更容易的連接到對應的操作。 ~~~ <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"/> ~~~ > 危險 > 操作必須在XML文件中對應的菜單之前聲明.數據文件是按順序執行的,操作的`id`必須在對應的菜單建立之前就存在于數據庫中。 > > 練習定義新菜單項,在開放學院菜單項下定義新菜單項來訪問課程。用戶應該能夠: > > * 顯示所有課程的列表 > * 建立或編輯課程 > 1.建立`openacademy/views/openacademy.xml`以創建操作和能夠觸發操作的菜單項。 > 2.添加這個文件到`openacademy/__manifest__.py`下的`data`列表。 `openacademy/__manifest__.py` ~~~ 'data': [ # 'security/ir.model.access.csv', 'templates.xml', 'views/openacademy.xml', ], # only loaded in demonstration mode 'demo': [ ~~~ `openacademy/views/openacademy.xml` ~~~ <?xml version="1.0" encoding="UTF-8"?> <odoo> <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> </odoo> ~~~ 作者:luohuayong 鏈接:http://www.jianshu.com/p/06e38310a465 來源:簡書 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看