由於自己並非資訊相關科系畢業,基礎知識與技能相當貧乏,透過此次學習Odoo系統基礎建置與開發,我才初次接觸了如何在Windows系統透過VM來使用Linux系統,以及終端機指令的操作,來一步一步建置Odoo系統,包括所需的Python套件、PostgreSQL資料庫系統、pgAdmin資料庫管理工具、Odoo系統資料夾結構、Odoo系統設定文件、PyCharm整合開發環境、系統更新與維護方式等等,需要了解與學習的技術非常非常的多,自己也僅學習使用了一小部分的工具與技巧而已。
系統開發由於牽涉到許多資料夾結構與不同文件如csv、py、xml等,因此未來使用Git做為示範檔案存放空間的需求或許也將越來越迫切,現階段仍純粹在網誌整理、發布文章;本系列一共六篇學習筆記,為花費大量時間綜合整理Peter Wu老師課堂教學、《Odoo快速入門與實戰》簡體書,以及零散的網路教學文章而得,前五篇的學習筆記完全操作使用Odoo社群版,第六篇的學習筆記則加入「康虎雲報表」的安裝與教學,可至「康虎軟件工作室」官方網站下載相關軟體,配合學習筆記的說明來安裝使用。
自學Odoo系統的建置開發相當不容易:在台灣,Odoo系統的知名度與普及性遠不如SAP、鼎新、Oracle等大廠,資訊廠商與開發人員的數量也相對稀少,就連參考書籍也完全沒有繁體中文的版本,僅有少數英文書與簡體書可以購買(而且這些書都寫得很糟),加上這幾年Odoo系統的快速發展,不同的版本之間有不小的變動,學會的技術可能過幾年就完全不能用了…。綜合上述許多原因,即便本系列學習筆記已經整理很清楚了,對於完全零經驗的開發者而言,相信仍舊難以閱讀、理解。
目前Odoo系統在歐美與中國大陸的資源、社群與討論,都比台灣頻繁、密集得多,想要入門Odoo系統的學習者建議還是需要老師來帶領,才有辦法掌握操作、管理、開發的各項眉眉角角。
l custom資料夾存放客製化開發模組的結構如下:
/openacademy
/data
/i18n
/models
/__init__.py
/security
/static
/description
/icon.png
/views
/wizards
__init__.py
__manifest__.py
/openacademy
/data
/i18n
/models
/__init__.py
/security
/static
/description
/icon.png
/views
/wizards
__init__.py
__manifest__.py
l data資料夾:
用以在資料庫自動放置資料、郵件模板。
用以在資料庫自動放置資料、郵件模板。
l i18n資料夾:
放置翻譯檔,為po檔案。
放置翻譯檔,為po檔案。
l models資料夾:
放置所設計欄位的py檔案。
放置所設計欄位的py檔案。
l security資料夾:
放置所規劃權限的csv檔案與xml檔案。
放置所規劃權限的csv檔案與xml檔案。
l static/description資料夾:
放置模組logo圖像等附件。
放置模組logo圖像等附件。
l views資料夾:
放置所設計頁面的xml檔案。
放置所設計頁面的xml檔案。
l wizards資料夾:
放置所設計彈出式視窗的py檔案與xml檔案。
放置所設計彈出式視窗的py檔案與xml檔案。
l __init__.py:
# -*- coding: utf-8 -*-
# Author: Peter Wu
# 載入models資料夾的Python程式碼
from . import models
# -*- coding: utf-8 -*-
# Author: Peter Wu
# 載入models資料夾的Python程式碼
from . import models
l __manifest__.py:
# -*- coding: utf-8 -*-
# Author: Peter Wu
# 安裝模組時顯示的資料
{
'name': 'Openacademy',
'version': '12',
# sequence代表該模組於安裝畫面顯示的順序
'sequence': 200,
'category': 'Student Academy Score system',
'website': 'https://www.alldo.com.tw',
'summary': 'Student Academy Score system',
'description': """
學生成績系統
""",
# 安裝使用該模組需要哪些模組的支援
'depends': [
],
# 模組所使用的csv檔案與xml檔案,需於此加入路徑名稱
'data': [
],
# 可安裝與否、可應用與否
'installable': True,
'application': True,
}
# -*- coding: utf-8 -*-
# Author: Peter Wu
# 安裝模組時顯示的資料
{
'name': 'Openacademy',
'version': '12',
# sequence代表該模組於安裝畫面顯示的順序
'sequence': 200,
'category': 'Student Academy Score system',
'website': 'https://www.alldo.com.tw',
'summary': 'Student Academy Score system',
'description': """
學生成績系統
""",
# 安裝使用該模組需要哪些模組的支援
'depends': [
],
# 模組所使用的csv檔案與xml檔案,需於此加入路徑名稱
'data': [
],
# 可安裝與否、可應用與否
'installable': True,
'application': True,
}
Openacademy模組範例一-學習基礎模組、Many2one字段、基礎權限
l Step 1在models資料夾內創建openacademy_student.py:
# -*- coding: utf-8 -*-
# Author: Peter Wu
from odoo import models, fields, api
from odoo.exceptions import UserError
# 整個Odoo系統的class名稱絕對不可以重複
# models.Model用在一般欄位
class openacademystudent(models.Model):
# 模型屬性說明:
# _name-與.py檔名盡量一致,是class的唯一標示字段,其它class可以通過此字段引用
# _description-類似於標籤,提高友善的查詢
# _rec_name-是record name的縮寫,Odoo預設使用物件名稱name做為一條紀錄的描述,我們可以藉由_rec_name指定其它的物件名稱
# _order-是在模型紀錄集展示時,預設的排序
# _table-是在模型裡面制定後台資料表名稱,預設資料表名稱是更改模型的名稱,把點(.)換成底線(_)
_name = 'openacademy.student'
_rec_name = 'student_name'
# 字段類型說明:
# 字串相關類型-fields.Char()、fields.Text()、fields.Selection()、fields.Html()
# 數值相關類型-fields.Integer()、fields.Float()
# 日期類型-fields.Date()、fields.Datetime()
# 布林類型-fields.Boolean()
# 二進制類型-fields.Binary()
# 字段屬性說明:
# string-是在前端介面看到的名稱
# help-是在前端介面看到的提示訊息
# default-設定預設值
# readonly-預設是False,如果設定為True,則在前端介面不可編輯
# required-預設是False,如果設定為True,則在創建紀錄時為必填,此項設置對模型層也是有作用的
# states-用字典來設定readonly、required、invisible三個屬性,例如states = {'done': ['readonly', True]}
# size-僅可使用在Char,限制最大字元數
# translate-僅可使用在Char、Text、Html,使文字可以被翻譯
# sequence-允許我們手動拖曳紀錄來定義順序,如要使用,要在模型屬性_order中引入
# index-預設是False,如果設定為True,則會在資料庫上創建索引
# groups-用於限定檢視該字段的security group
# deprecated-如果設定為True,則一旦使用該字段,就會在日誌中記錄警告訊息
# copy-預設是True,如果設定為False,則在複製紀錄時,該字段不被複製
# active-如果設定為False,則在前端查詢時,該紀錄會被排除在外
# oldname-可以在複製紀錄時,使舊版本的數據自動複製到對應的新字段
student_no = fields.Char(string = '學生學號', required = True)
student_name = fields.Char(string = '學生姓名', required = True)
student_contact = fields.Char(string = '聯絡人')
student_class = fields.Selection([('1', '一年級'), ('2', '二年級'), ('3', '三年級')], string = '年級')
student_fm = fields.Selection([('M', '男'), ('F', '女')], string = '性別', default = 'M')
# 我們可以自由創建student_no等物件,但以下保留字段不可使用:
# _last_update-並不會實際存儲值,僅有觸發檢查的作用
# id-是紀錄的唯一標示
# create_date-記錄創建的日期
# create_uid-創建Many2one類型紀錄的用戶
# write_date-記錄的最後修改日期
# write_uid-最後修改Many2one類型紀錄的用戶
# -*- coding: utf-8 -*-
# Author: Peter Wu
from odoo import models, fields, api
from odoo.exceptions import UserError
# 整個Odoo系統的class名稱絕對不可以重複
# models.Model用在一般欄位
class openacademystudent(models.Model):
# 模型屬性說明:
# _name-與.py檔名盡量一致,是class的唯一標示字段,其它class可以通過此字段引用
# _description-類似於標籤,提高友善的查詢
# _rec_name-是record name的縮寫,Odoo預設使用物件名稱name做為一條紀錄的描述,我們可以藉由_rec_name指定其它的物件名稱
# _order-是在模型紀錄集展示時,預設的排序
# _table-是在模型裡面制定後台資料表名稱,預設資料表名稱是更改模型的名稱,把點(.)換成底線(_)
_name = 'openacademy.student'
_rec_name = 'student_name'
# 字段類型說明:
# 字串相關類型-fields.Char()、fields.Text()、fields.Selection()、fields.Html()
# 數值相關類型-fields.Integer()、fields.Float()
# 日期類型-fields.Date()、fields.Datetime()
# 布林類型-fields.Boolean()
# 二進制類型-fields.Binary()
# 字段屬性說明:
# string-是在前端介面看到的名稱
# help-是在前端介面看到的提示訊息
# default-設定預設值
# readonly-預設是False,如果設定為True,則在前端介面不可編輯
# required-預設是False,如果設定為True,則在創建紀錄時為必填,此項設置對模型層也是有作用的
# states-用字典來設定readonly、required、invisible三個屬性,例如states = {'done': ['readonly', True]}
# size-僅可使用在Char,限制最大字元數
# translate-僅可使用在Char、Text、Html,使文字可以被翻譯
# sequence-允許我們手動拖曳紀錄來定義順序,如要使用,要在模型屬性_order中引入
# index-預設是False,如果設定為True,則會在資料庫上創建索引
# groups-用於限定檢視該字段的security group
# deprecated-如果設定為True,則一旦使用該字段,就會在日誌中記錄警告訊息
# copy-預設是True,如果設定為False,則在複製紀錄時,該字段不被複製
# active-如果設定為False,則在前端查詢時,該紀錄會被排除在外
# oldname-可以在複製紀錄時,使舊版本的數據自動複製到對應的新字段
student_no = fields.Char(string = '學生學號', required = True)
student_name = fields.Char(string = '學生姓名', required = True)
student_contact = fields.Char(string = '聯絡人')
student_class = fields.Selection([('1', '一年級'), ('2', '二年級'), ('3', '三年級')], string = '年級')
student_fm = fields.Selection([('M', '男'), ('F', '女')], string = '性別', default = 'M')
# 我們可以自由創建student_no等物件,但以下保留字段不可使用:
# _last_update-並不會實際存儲值,僅有觸發檢查的作用
# id-是紀錄的唯一標示
# create_date-記錄創建的日期
# create_uid-創建Many2one類型紀錄的用戶
# write_date-記錄的最後修改日期
# write_uid-最後修改Many2one類型紀錄的用戶
l Step 2在models資料夾內修改__init__.py:
# -*- coding: utf-8 -*-
# Author : Peter Wu
from . import openacademy_student
# -*- coding: utf-8 -*-
# Author : Peter Wu
from . import openacademy_student
l Step 3在models資料夾內創建openacademy_score.py:
# -*- coding: utf-8 -*-
# Author: Peter Wu
from odoo import models, fields, api
from odoo.exceptions import UserError
class openacademyscore(models.Model):
_name = 'openacademy.score'
score_year = fields.Char(string = '學年', required = True)
# Many2one字段屬性說明:
# comodel-設置與本模型關聯的另一個模型的名稱
# string-是在前端介面看到的名稱
# ondelete-刪除關聯紀錄時本字段的動作-
預設是set null-關聯紀錄被刪除時本字段將被賦值為null;
restricted-關聯紀錄被刪除時會報錯,阻止關聯字段被刪除;
cascade-關聯字段被刪除則本紀錄也將被刪除
# context-關聯資料時附帶訊息,例如設置預設值
# domain-設定查詢條件,用於限定查詢的數據
# auto_join-將會繞過查看的安全規則,用戶可以查看權限以外的數據
score_student = fields.Many2one('openacademy.student', string = '學生', required = True)
score_chinese = fields.Float(string = '國文分數', default = 0)
score_math = fields.Float(string = '數學分數', default = 0)
score_english = fields.Float(string = '英文分數', default = 0)
# -*- coding: utf-8 -*-
# Author: Peter Wu
from odoo import models, fields, api
from odoo.exceptions import UserError
class openacademyscore(models.Model):
_name = 'openacademy.score'
score_year = fields.Char(string = '學年', required = True)
# Many2one字段屬性說明:
# comodel-設置與本模型關聯的另一個模型的名稱
# string-是在前端介面看到的名稱
# ondelete-刪除關聯紀錄時本字段的動作-
預設是set null-關聯紀錄被刪除時本字段將被賦值為null;
restricted-關聯紀錄被刪除時會報錯,阻止關聯字段被刪除;
cascade-關聯字段被刪除則本紀錄也將被刪除
# context-關聯資料時附帶訊息,例如設置預設值
# domain-設定查詢條件,用於限定查詢的數據
# auto_join-將會繞過查看的安全規則,用戶可以查看權限以外的數據
score_student = fields.Many2one('openacademy.student', string = '學生', required = True)
score_chinese = fields.Float(string = '國文分數', default = 0)
score_math = fields.Float(string = '數學分數', default = 0)
score_english = fields.Float(string = '英文分數', default = 0)
l Step 4在models資料夾內修改__init__.py:
# 原程式碼增加以下程式碼
from . import openacademy_score
# 原程式碼增加以下程式碼
from . import openacademy_score
l Step 5在views資料夾內創建openacademy_student.xml;
因為已將setting.jar匯入Live templates,可使用編輯技巧-
輸入odoo_data再按Tab鍵、
輸入odoo_tree再按Tab鍵、
輸入odoo_form再按Tab鍵、
輸入odoo_view_action再按Tab鍵:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!--顯示外層橫式的表格畫面-->
<!--model屬性標示本紀錄要使用的模型-->
<!--id屬性在整個Odoo系統中不可以重複,而且id的命名規則最多只能有一個點(.)-->
<record id="view_openacademy_student_tree" model="ir.ui.view">
<field name="name">view.openacademy.student.tree</field>
<field name="model">openacademy.student</field>
<field name="arch" type="xml">
<tree string="">
<field name="student_no"/>
<field name="student_name"/>
<field name="student_contact"/>
<field name="student_class"/>
<field name="student_fm"/>
</tree>
</field>
</record>
<!--顯示內層直式的表格畫面-->
<record id="view_openacademy_student_form" model="ir.ui.view">
<field name="name">view.openacademy.student.form</field>
<field name="model">openacademy.student</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="student_no"/>
<field name="student_name"/>
<field name="student_contact"/>
<field name="student_class"/>
<field name="student_fm"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_openacademy_student_view" model="ir.actions.act_window">
<field name="name">學生基本資料</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">openacademy.student</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create"></p>
<p></p>
</field>
</record>
</data>
</odoo>
因為已將setting.jar匯入Live templates,可使用編輯技巧-
輸入odoo_data再按Tab鍵、
輸入odoo_tree再按Tab鍵、
輸入odoo_form再按Tab鍵、
輸入odoo_view_action再按Tab鍵:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!--顯示外層橫式的表格畫面-->
<!--model屬性標示本紀錄要使用的模型-->
<!--id屬性在整個Odoo系統中不可以重複,而且id的命名規則最多只能有一個點(.)-->
<record id="view_openacademy_student_tree" model="ir.ui.view">
<field name="name">view.openacademy.student.tree</field>
<field name="model">openacademy.student</field>
<field name="arch" type="xml">
<tree string="">
<field name="student_no"/>
<field name="student_name"/>
<field name="student_contact"/>
<field name="student_class"/>
<field name="student_fm"/>
</tree>
</field>
</record>
<!--顯示內層直式的表格畫面-->
<record id="view_openacademy_student_form" model="ir.ui.view">
<field name="name">view.openacademy.student.form</field>
<field name="model">openacademy.student</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="student_no"/>
<field name="student_name"/>
<field name="student_contact"/>
<field name="student_class"/>
<field name="student_fm"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_openacademy_student_view" model="ir.actions.act_window">
<field name="name">學生基本資料</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">openacademy.student</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create"></p>
<p></p>
</field>
</record>
</data>
</odoo>
l Step 6在views資料夾內創建openacademy_score.xml:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_openacademy_score_tree" model="ir.ui.view">
<field name="name">view.openacademy.score.tree</field>
<field name="model">openacademy.score</field>
<field name="arch" type="xml">
<tree string="">
<field name="score_year"/>
<field name="score_student"/>
<field name="score_chinese"/>
<field name="score_math"/>
<field name="score_english"/>
</tree>
</field>
</record>
<record id="view_openacademy_score_form" model="ir.ui.view">
<field name="name">view.openacademy.score.form</field>
<field name="model">openacademy.score</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="score_year"/>
<field name="score_student"/>
<field name="score_chinese"/>
<field name="score_math"/>
<field name="score_english"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_openacademy_score_view" model="ir.actions.act_window">
<field name="name">學期成績紀錄</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">openacademy.score</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create"></p>
<p></p>
</field>
</record>
</data>
</odoo>
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_openacademy_score_tree" model="ir.ui.view">
<field name="name">view.openacademy.score.tree</field>
<field name="model">openacademy.score</field>
<field name="arch" type="xml">
<tree string="">
<field name="score_year"/>
<field name="score_student"/>
<field name="score_chinese"/>
<field name="score_math"/>
<field name="score_english"/>
</tree>
</field>
</record>
<record id="view_openacademy_score_form" model="ir.ui.view">
<field name="name">view.openacademy.score.form</field>
<field name="model">openacademy.score</field>
<field name="arch" type="xml">
<form string="">
<sheet>
<group>
<field name="score_year"/>
<field name="score_student"/>
<field name="score_chinese"/>
<field name="score_math"/>
<field name="score_english"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_openacademy_score_view" model="ir.actions.act_window">
<field name="name">學期成績紀錄</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">openacademy.score</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create"></p>
<p></p>
</field>
</record>
</data>
</odoo>
l Step 7在views資料夾內創建openacademy_menu.xml;
因為已將setting.jar匯入Live templates,可使用編輯技巧-
輸入odoo_data再按Tab鍵、
輸入odoo_menuitem_root再按Tab鍵、
輸入odoo_menuitem_categ再按Tab鍵、
輸入odoo_menuitem_action再按Tab鍵:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<menuitem id="menu_openacademy_root"
name="學生成績系統"
sequence="200"/>
<menuitem id="menu_openacademy_categ"
name="基礎資料"
parent="menu_openacademy_root"
sequence="10"/>
<menuitem id="menu_openacademy_student_view"
name="" parent="menu_openacademy_categ"
action="action_openacademy_student_view"
sequence="10"/>
<menuitem id="menu_openacademy_score_categ"
name="成績紀錄"
parent="menu_openacademy_root"
sequence="20"/>
<menuitem id="menu_openacademy_score_view"
name="" parent="menu_openacademy_score_categ"
action="action_openacademy_score_view"
sequence="10"/>
</data>
</odoo>
因為已將setting.jar匯入Live templates,可使用編輯技巧-
輸入odoo_data再按Tab鍵、
輸入odoo_menuitem_root再按Tab鍵、
輸入odoo_menuitem_categ再按Tab鍵、
輸入odoo_menuitem_action再按Tab鍵:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<menuitem id="menu_openacademy_root"
name="學生成績系統"
sequence="200"/>
<menuitem id="menu_openacademy_categ"
name="基礎資料"
parent="menu_openacademy_root"
sequence="10"/>
<menuitem id="menu_openacademy_student_view"
name="" parent="menu_openacademy_categ"
action="action_openacademy_student_view"
sequence="10"/>
<menuitem id="menu_openacademy_score_categ"
name="成績紀錄"
parent="menu_openacademy_root"
sequence="20"/>
<menuitem id="menu_openacademy_score_view"
name="" parent="menu_openacademy_score_categ"
action="action_openacademy_score_view"
sequence="10"/>
</data>
</odoo>
l Step 8在security資料夾內創建ir.model.access.csv,分別建立openacademy_student與openacademy_score兩個模型的權限:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
"access_openacademy_score","access.openacademy.score","openacademy.model_openacademy_score","base.group_user","True","True","True","True"
"access_openacademy_student","access.openacademy.student","openacademy.model_openacademy_student","base.group_user","True","True","True","True"
欄位說明如下:
id-紀錄的唯一標示。
name-紀錄的唯一名稱,命名方法是用點(.)連接模組名稱。
model_id-是設置訪問權限的模組_name,_name如果是bm.bug,model_id就是model_bm_bug。
group_id-是我們要授予權限的security group id,例如base.group_user。
perm-對應讀、寫、新建、刪除操作的設置。
未來可由Settings > Activate the developer mode > Technical > Access Right匯出csv檔快速建立檔案,如下圖。
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
"access_openacademy_score","access.openacademy.score","openacademy.model_openacademy_score","base.group_user","True","True","True","True"
"access_openacademy_student","access.openacademy.student","openacademy.model_openacademy_student","base.group_user","True","True","True","True"
欄位說明如下:
id-紀錄的唯一標示。
name-紀錄的唯一名稱,命名方法是用點(.)連接模組名稱。
model_id-是設置訪問權限的模組_name,_name如果是bm.bug,model_id就是model_bm_bug。
group_id-是我們要授予權限的security group id,例如base.group_user。
perm-對應讀、寫、新建、刪除操作的設置。
未來可由Settings > Activate the developer mode > Technical > Access Right匯出csv檔快速建立檔案,如下圖。
l Step 9修改__manifest__.py:
# 模組所使用的csv檔案與xml檔案,需於此加入路徑名稱
'data': [
# 因程式執行有順序性,權限檔案建議放在最前面
'security/ir.model.access.csv',
'views/openacademy_student.xml',
'views/openacademy_score.xml',
# 因程式執行有順序性,menu一定要放在最後面
'views/openacademy_menu.xml',
],
# 模組所使用的csv檔案與xml檔案,需於此加入路徑名稱
'data': [
# 因程式執行有順序性,權限檔案建議放在最前面
'security/ir.model.access.csv',
'views/openacademy_student.xml',
'views/openacademy_score.xml',
# 因程式執行有順序性,menu一定要放在最後面
'views/openacademy_menu.xml',
],
l Step 10登入Odoo系統檢視客製化開發結果:
Settings > Activate the developer mode
Apps > Update Apps List > INSTALL Openacademy
Settings > Activate the developer mode
Apps > Update Apps List > INSTALL Openacademy
l 補充一:
未來若只修改models資料夾的Python程式碼,不需要UPGRADE模組即可檢視客製化開發結果,但若不只修改Python程式碼,例如修改xml檔案,則需要UPGRADE模組。
未來若只修改models資料夾的Python程式碼,不需要UPGRADE模組即可檢視客製化開發結果,但若不只修改Python程式碼,例如修改xml檔案,則需要UPGRADE模組。
l 補充二:
Activate the developer mode-在Odoo中為了加快速度,頁面端對JavaScript和CSS資源進行了壓縮。
Activate the developer mode (with assets)-會加載頁面需要的JavaScript和CSS資源,但這會導致頁面的瀏覽速度有所下降。
Activate the developer mode-在Odoo中為了加快速度,頁面端對JavaScript和CSS資源進行了壓縮。
Activate the developer mode (with assets)-會加載頁面需要的JavaScript和CSS資源,但這會導致頁面的瀏覽速度有所下降。
更新Odoo 12、更新PostgreSQL資料庫
l 在終端機輸入指令更新Odoo 12:
cd /opt/odoo/odoo
sudo git pull origin 12.0
cd /opt/odoo/odoo
sudo git pull origin 12.0
l 開啟Pycharm,點選Run > Edit Configurations...,修改Parameters設定,資料庫名稱以odoo12為例,設定完成後點選OK,再點選Run > Run 'odoo12',這個動作會將更新寫入PostgreSQL資料庫,執行完畢記得將Parameters改回來:
-c /etc/odoo.conf -u all -d odoo12
-c /etc/odoo.conf -u all -d odoo12
忘記Odoo系統管理員的密碼
l 在終端機輸入指令登入PostgreSQL資料庫,資料庫名稱以odoo12為例,帳號以admin為例:
psql -d odoo12
select login from res_users;
update res_users set password='123456' where login='admin';
\q
psql -d odoo12
select login from res_users;
update res_users set password='123456' where login='admin';
\q
沒有留言:
張貼留言