本文是 Odoo 12.0 官方教程第二篇 建立網(wǎng)站
查看英文原文:
https://www.odoo.com/documentation/12.0/howtos/website.html
以下內(nèi)容為機(jī)器翻譯茫叭,半人工校對,僅供參考。
建立網(wǎng)站
警告
- 本指南假設(shè) Python 的基本知識
- 本指南假設(shè) 已安裝 Odoo
創(chuàng)建一個基本模塊
在 Odoo,任務(wù)是通過創(chuàng)建模塊。
模塊定制的 Odoo 設(shè)施的行為奶段,通過添加新的行為或改變現(xiàn)有的(包括行為由其他模塊添加)。
Odoo 的腳手架 可以設(shè)置一個基本模塊。很快開始簡單地調(diào)用:
$ ./odoo-bin scaffold Academy my-modules
這將自動創(chuàng)建一個 my-modules
模塊目錄 和一個 academy
模塊. 如果您想要的話北秽,該目錄可以是一個現(xiàn)有的模塊目錄,但該模塊名必須是唯一的目錄最筒。
示范模塊
我們有一個“完成”模塊準(zhǔn)備安裝贺氓。
雖然它沒有絕對沒有,我們可以安裝它:
-
啟動 odoo 服務(wù)器
$ ./odoo-bin --addons-path addons,my-modules
創(chuàng)建一個新的數(shù)據(jù)庫床蜘,包括演示數(shù)據(jù)
去 設(shè)置?模塊?模塊
在右上角的刪除 Installed 過濾器然后搜索 academy
點(diǎn)擊 Academy 模塊的安裝按鈕
到瀏覽器
Controllers 解釋瀏覽器請求并發(fā)送數(shù)據(jù)辙培。
添加一個簡單的控制器,并確保它是導(dǎo)入的 __init__.py
(所以邢锯,Odoo 可以找到它):
academy/controllers.py
# -*- coding: utf-8 -*-
from odoo import http
class Academy(http.Controller):
@http.route('/academy/academy/', auth='public')
def index(self, **kw):
return "Hello, world"
# @http.route('/academy/academy/objects/', auth='public')
# def list(self, **kw):
關(guān)閉您的服務(wù)器 (^C
) 然后重新啟動它:
$ ./odoo-bin --addons-path addons,my-modules
打開一頁 http://localhost:8069/academy/academy/, 你應(yīng)該看到你的“頁面”出現(xiàn):
模板
在 Python 中生成 HTML 不總是水到渠成扬蕊。
通常的解決方案是 templates, 偽文件的占位符和顯示邏輯。Odoo 允許任何 Python 模板系統(tǒng)丹擎,但提供了自己 QWeb 模板系統(tǒng)集成了其他功能尾抑。
創(chuàng)建一個模板,確保模板文件被注冊到 __manifest__.py
清單, 并改變控制器使用我們的模板:
academy/controllers.py
class Academy(http.Controller):
@http.route('/academy/academy/', auth='public')
def index(self, **kw):
return http.request.render('academy.index', {
'teachers': ["Diana Padilla", "Jody Caroll", "Lester Vaughn"],
})
# @http.route('/academy/academy/objects/', auth='public')
# def list(self, **kw):
academy/templates.xml
<odoo>
<template id="index">
<title>Academy</title>
<t t-foreach="teachers" t-as="teacher">
<p><t t-esc="teacher"/></p>
</t>
</template>
<!-- <template id="object"> -->
<!-- <h1><t t-esc="object.display_name"/></h1> -->
<!-- <dl> -->
模板:(t-foreach
)對所有教師(通過 模板上下文)蒂培,并打印每個老師在自己的段落再愈。
最后重啟 Odoo 和更新模塊的數(shù)據(jù)(安裝模板)去 設(shè)置?模塊?模塊之間的 ?點(diǎn)擊升級。
提示
另外护戳,Odoo 可以重新開始 和更新模塊在同一時間<odoo-bin -u>
:
$ odoo-bin --addons-path addons,my-modules -d academy -u academy
打開 http://localhost:8069/academy/academy/ 現(xiàn)在應(yīng)該導(dǎo)致:
在 Odoo 存儲數(shù)據(jù)
Odoo models map to database tables.
在上一節(jié)中我們只顯示一個列表的字符串輸入靜態(tài)的 Python 代碼翎冲。這不允許修改或持久存儲,所以我們現(xiàn)在將我們的數(shù)據(jù)移到數(shù)據(jù)庫中媳荒。
定義數(shù)據(jù)模型
定義一個教師模型抗悍,并確保它是從 __init__.py
所以它被正確地加載:
academy/models.py
from odoo import models, fields, api
class Teachers(models.Model):
_name = 'academy.teachers'
name = fields.Char()
然后設(shè)置 basic access control 為模型,并將它們添加到清單:
academy/manifest.py
# always loaded
'data': [
'security/ir.model.access.csv',
'templates.xml',
],
# only loaded in demonstration mode
academy/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,0,0,0
這就簡單地給出讀訪問 (perm_read
) 給所有用戶 (group_id:id
left empty).
Note
數(shù)據(jù)文件 (XML 或 CSV) 必須添加到模塊清單肺樟,Python 文件 (模型或控制器) 不要檐春,但必須從進(jìn)口 __init__.py
(直接或間接)
Warning
管理員用戶繞過訪問控制,他們可以訪問所有的模型么伯,即使無法獲得
示范數(shù)據(jù)
第二步是向系統(tǒng)中添加一些演示數(shù)據(jù)疟暖,這樣就可以很容易地測試它了。這是通過添加一個 demo
數(shù)據(jù)文件, 這必須從清單鏈接:
academy/demo.xml
<odoo>
<record id="padilla" model="academy.teachers">
<field name="name">Diana Padilla</field>
</record>
<record id="carroll" model="academy.teachers">
<field name="name">Jody Carroll</field>
</record>
<record id="vaughn" model="academy.teachers">
<field name="name">Lester Vaughn</field>
</record>
</odoo>
Tip
數(shù)據(jù)文件 可用于演示和非演示數(shù)據(jù)。演示數(shù)據(jù)只加載在“示范模式”俐巴,可用于流量測試和演示骨望,非演示數(shù)據(jù)總是加載和用作初始系統(tǒng)設(shè)置。
在這種情況下欣舵,我們使用演示數(shù)據(jù)擎鸠,因?yàn)樵撓到y(tǒng)的實(shí)際用戶將要輸入或輸入自己的老師列表,這個列表僅用于測試缘圈。
訪問數(shù)據(jù)
最后一步是修改模型和模板來使用我們的演示數(shù)據(jù):
- 從數(shù)據(jù)庫中讀取記錄劣光,而不是靜態(tài)列表
- 因?yàn)?
search()
返回一組匹配濾波器的記錄(“所有記錄”在這里),改變模板打印每一個老師的名字
academy/controllers.py
class Academy(http.Controller):
@http.route('/academy/academy/', auth='public')
def index(self, **kw):
Teachers = http.request.env['academy.teachers']
return http.request.render('academy.index', {
'teachers': Teachers.search([])
})
# @http.route('/academy/academy/objects/', auth='public')
academy/templates.xml
<template id="index">
<title>Academy</title>
<t t-foreach="teachers" t-as="teacher">
<p><t t-esc="teacher.id"/> <t t-esc="teacher.name"/></p>
</t>
</template>
<!-- <template id="object"> -->
重新啟動服務(wù)器并更新模塊(以更新清單和模板并加載該演示文件)然后導(dǎo)航到http://localhost:8069/academy/academy/. 網(wǎng)頁應(yīng)該略有不同:名稱應(yīng)簡單地以一個數(shù)字(老師用的數(shù)據(jù)庫標(biāo)識符)糟把。
網(wǎng)站支持
Odoo 束模塊致力于網(wǎng)站建設(shè)绢涡。
到目前為止,我們已經(jīng)使用的控制器相當(dāng)直接遣疯,但 Odoo 8 添加更深層次的整合和一些其他的服務(wù)(例如雄可,默認(rèn)的樣式、主題)通過 網(wǎng)站
模塊缠犀。
- 首先, 請?zhí)砑?
website
作為一個依賴academy
- 然后加入
website=True
控制器上的標(biāo)志数苫,這設(shè)置了一些新的變量 請求對象 并允許使用網(wǎng)站布局在我們的模板 - 使用網(wǎng)站布局模板
academy/manifest.py
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['website'],
# always loaded
'data': [
academy/controllers.py
from odoo import http
class Academy(http.Controller):
@http.route('/academy/academy/', auth='public', website=True)
def index(self, **kw):
Teachers = http.request.env['academy.teachers']
return http.request.render('academy.index', {
academy/templates.xml
<odoo>
<template id="index">
<t t-call="website.layout">
<t t-set="title">Academy</t>
<div class="oe_structure">
<div class="container">
<t t-foreach="teachers" t-as="teacher">
<p><t t-esc="teacher.id"/> <t t-esc="teacher.name"/></p>
</t>
</div>
</div>
</t>
</template>
<!-- <template id="object"> -->
在重新啟動服務(wù)器的同時更新模塊(以更新清單和模板)訪問http://localhost:8069/academy/academy/ 應(yīng)該得到一個更好的頁面與品牌和一些內(nèi)置的頁面元素(頂級菜單,腳注辨液,…)
網(wǎng)站的布局也提供了編輯工具支持:在 標(biāo)志點(diǎn)擊 (前右)虐急,填寫證書 (admin
/ admin
默認(rèn)) 然后點(diǎn)擊 登錄.
你現(xiàn)在在 Odoo “適當(dāng)?shù)摹保汗芾斫缑妗,F(xiàn)在點(diǎn)擊 網(wǎng)站 菜單(左上角室梅。
我們回到網(wǎng)站戏仓,但作為管理員,獲得高級版的功能 website 提供支持:
- 模板代碼編輯器(自定義?HTML編輯器)亡鼠,您可以查看和編輯用于當(dāng)前頁的所有模板
- 的 編輯 按鈕在左上角切換到“編輯模式”在蓋帽(片段)和富文本版是可用的
- 其他一些功能如移動預(yù)覽或 SEO
網(wǎng)址和路由
控制器方法與 routes 通過 route()
設(shè)計(jì)師以路由串和一些屬性來定制其行為或安全赏殃。
我們已經(jīng)看到了一個“文本”的路由字符串,它匹配的一個地址部分间涵,但也可以使用路由字符串 converter patterns 匹配位的網(wǎng)址仁热,并使那些可用的本地變量。例如勾哩,我們可以創(chuàng)建一個新的控制器的方法抗蠢,需要一點(diǎn)的網(wǎng)址和打印出來:
academy/controllers.py
'teachers': Teachers.search([])
})
@http.route('/academy/<name>/', auth='public', website=True)
def teacher(self, name):
return '<h1>{}</h1>'.format(name)
# @http.route('/academy/academy/objects/', auth='public')
# def list(self, **kw):
# return http.request.render('academy.listing', {
重啟 Odoo, 訪問 http://localhost:8069/academy/Alice/ 和 http://localhost:8069/academy/Bob/ 看到差異。
正如名字所顯示的, converter patterns 不要只做提取思劳,他們也 驗(yàn)證 和 轉(zhuǎn)換迅矛,所以我們可以改變新的控制器只接受整數(shù):
academy/controllers.py
'teachers': Teachers.search([])
})
@http.route('/academy/<int:id>/', auth='public', website=True)
def teacher(self, id):
return '<h1>{} ({})</h1>'.format(id, type(id).__name__)
# @http.route('/academy/academy/objects/', auth='public')
重啟 Odoo, 訪問 http://localhost:8069/academy/2, 請注意,舊的值是字符串潜叛,但新的一個被轉(zhuǎn)換為一個整數(shù)秽褒。嘗試訪問 http://localhost:8069/academy/Carol/ 并注意到該頁并沒有找到:因?yàn)?“Carol” 是不是一個整數(shù)壶硅,這條路線被忽略,沒有找到路線销斟。
Odoo 提供了一個額外的轉(zhuǎn)換稱為 模型
提供記錄時直接給他們的ID庐椒。讓我們用這個來創(chuàng)建通用老師傳記的一頁:
academy/controllers.py
'teachers': Teachers.search([])
})
@http.route('/academy/<model("academy.teachers"):teacher>/', auth='public', website=True)
def teacher(self, teacher):
return http.request.render('academy.biography', {
'person': teacher
})
# @http.route('/academy/academy/objects/', auth='public')
academy/templates.xml
</div>
</t>
</template>
<template id="biography">
<t t-call="website.layout">
<t t-set="title">Academy</t>
<div class="oe_structure"/>
<div class="oe_structure">
<div class="container">
<p><t t-esc="person.id"/> <t t-esc="person.name"/></p>
</div>
</div>
<div class="oe_structure"/>
</t>
</template>
<!-- <template id="object"> -->
<!-- <h1><t t-esc="object.display_name"/></h1> -->
<!-- <dl> -->
然后改變模型的列表,以連接到我們的新控制器:
academy/templates.xml
<div class="oe_structure">
<div class="container">
<t t-foreach="teachers" t-as="teacher">
<p><a t-attf-href="/academy/{{ slug(teacher) }}">
<t t-esc="teacher.name"/></a>
</p>
</t>
</div>
</div>
<div class="oe_structure"/>
<div class="oe_structure">
<div class="container">
<h3><t t-esc="person.name"/></h3>
</div>
</div>
<div class="oe_structure"/>
重啟 Odoo 升級模塊蚂踊,那么你就可以訪問每個老師的網(wǎng)頁约谈。作為一個練習(xí),試著在老師的頁面添加塊寫一篇傳記犁钟,然后去另一個老師的網(wǎng)頁等等棱诱。你會發(fā)現(xiàn),你的傳記之間的所有教師共享涝动,因?yàn)閴K添加到 模板军俊,和 傳 模板之間的所有教師共享的,當(dāng)一個網(wǎng)頁編輯捧存,他們都在同一時間編輯。
字段編輯
具體到記錄的數(shù)據(jù)應(yīng)該保存在該記錄中担败,所以讓我們給我們的老師添加一個新的 biography 字段:
academy/models.py
_name = 'academy.teachers'
name = fields.Char()
biography = fields.Html()
academy/templates.xml
<div class="oe_structure">
<div class="container">
<h3><t t-esc="person.name"/></h3>
<div><t t-esc="person.biography"/></div>
</div>
</div>
<div class="oe_structure"/>
重啟 Odoo 和更新的觀點(diǎn)昔穴,重新載入老師的網(wǎng)頁和…的領(lǐng)域是看不見的因?yàn)樗缓腥魏巍?/p>
記錄字段模板可以使用一個特殊的 t-field
指令允許使用領(lǐng)域特定接口的網(wǎng)站編輯的字段內(nèi)容。改變的 person 模板使用 t-field
:
academy/templates.xml
<div class="oe_structure"/>
<div class="oe_structure">
<div class="container">
<h3 t-field="person.name"/>
<div t-field="person.biography"/>
</div>
</div>
<div class="oe_structure"/>
重啟 Odoo 升級模塊提前,現(xiàn)在有一個占位符的老師的名字吗货,在 側(cè)塊新區(qū)域。含量下降有存放在相應(yīng)的教師 biography
領(lǐng)域狈网,進(jìn)而具體教師宙搬。
老師的名字是可編輯的,當(dāng)保存更改索引頁上可見拓哺。
t-field
也可以采取的精確字段的格式選項(xiàng)勇垛。例如,如果我們顯示教師的記錄的修改日期:
academy/templates.xml
<div class="oe_structure">
<div class="container">
<h3 t-field="person.name"/>
<p>Last modified: <i t-field="person.write_date"/></p>
<div t-field="person.biography"/>
</div>
</div>
這是一個 “電腦” 的使用方式和難讀出來士鸥,但我們可以問一個人類可讀的版本:
academy/templates.xml
<div class="oe_structure">
<div class="container">
<h3 t-field="person.name"/>
<p>Last modified: <i t-field="person.write_date" t-options='{"format": "long"}'/></p>
<div t-field="person.biography"/>
</div>
</div>
或相對顯示:
academy/templates.xml
<div class="oe_structure">
<div class="container">
<h3 t-field="person.name"/>
<p>Last modified: <i t-field="person.write_date" t-options='{"widget": "relative"}'/></p>
<div t-field="person.biography"/>
</div>
</div>
管理和企業(yè)管理系統(tǒng)集成
一個簡單的和不完全的 Odoo 管理導(dǎo)論
Odoo 管理作了簡要的出現(xiàn)在 website support 剖面闲孤。我們可以回到它使用 管理員?管理員 菜單中(或 登錄 如果你簽出)。
Odoo 后端的概念結(jié)構(gòu)簡單:
- 首先是菜單烤礁,一棵樹(菜單可以有子菜單)的記錄讼积。沒有兒童地圖菜單…
- 行動。行動有多種類型:鏈接脚仔、報道勤众,代碼 Odoo 應(yīng)執(zhí)行或數(shù)據(jù)顯示。數(shù)據(jù)顯示的行動被稱為 窗的 動作 鲤脏,并告訴 Odoo 顯示給定 模型 根據(jù)一組視圖…
- 一個視圖有一個類型们颜,一個廣泛的領(lǐng)域吕朵,它對應(yīng)(列表、圖表掌桩、日歷)和 架構(gòu) 边锁,定做的模型是在視圖的顯示方式。
在 Odoo 管理編輯
默認(rèn)情況下波岛,一個 Odoo 模型是用戶基本上看不見的茅坛。為了使其可見,它必須通過一個行動则拷,它本身需要是可到達(dá)的贡蓖,一般通過菜單。
讓我們?yōu)槲覀兊哪P蛣?chuàng)建一個菜單:
academy/manifest.py
'data': [
'security/ir.model.access.csv',
'templates.xml',
'views.xml',
],
# only loaded in demonstration mode
'demo': [
academy/views.xml
<odoo>
<record id="action_academy_teachers" model="ir.actions.act_window">
<field name="name">Academy teachers</field>
<field name="res_model">academy.teachers</field>
</record>
<menuitem sequence="0" id="menu_academy" name="Academy"/>
<menuitem id="menu_academy_content" parent="menu_academy"
name="Academy Content"/>
<menuitem id="menu_academy_content_teachers"
parent="menu_academy_content"
action="action_academy_teachers"/>
訪問 http://localhost:8069/web/ 在左上方應(yīng)該是一個菜單 學(xué)院煌茬,這是默認(rèn)選中的斥铺,因?yàn)樗堑谝粋€菜單,并且打開上市的教師坛善。從上市有可能創(chuàng)造新 老師記錄晾蜘,并通過記錄視圖切換到“窗體”。
如果沒有定義如何呈現(xiàn)記錄 (a view) Odoo 將自動創(chuàng)建一個基本的飛行眠屎。在我們的情況下剔交,它的“列表”視圖(只顯示現(xiàn)在的老師的名字)但在“表” 視圖的 HTML biography
場并排顯示的 名字
領(lǐng)域并沒有給予足夠的空間。讓我們來定義一個自定義表單視圖來查看和編輯老師記錄一個更好的體驗(yàn):
academy/views.xml
<field name="res_model">academy.teachers</field>
</record>
<record id="academy_teacher_form" model="ir.ui.view">
<field name="name">Academy teachers: form</field>
<field name="model">academy.teachers</field>
<field name="arch" type="xml">
<form>
<sheet>
<label for="name"/> <field name="name"/>
<label for="biography"/>
<field name="biography"/>
</sheet>
</form>
</field>
</record>
<menuitem sequence="0" id="menu_academy" name="Academy"/>
<menuitem id="menu_academy_content" parent="menu_academy" name="Academy Content"/>
關(guān)系模型
我們已經(jīng)看到了一對 "basic" 直接存儲在該記錄中的字段改衩。有 一些基本字段. 第二類字段 relational 和用于鏈接到另一個(在一個模型或跨模型)的記錄岖常。
示范,讓我們創(chuàng)建一個 課程 模型葫督。每門課程都應(yīng)該有一個 老師
領(lǐng)域竭鞍,鏈接到一個單一的老師的記錄,但每一個老師可以教很多課程:
academy/models.py
name = fields.Char()
biography = fields.Html()
class Courses(models.Model):
_name = 'academy.courses'
name = fields.Char()
teacher_id = fields.Many2one('academy.teachers', string="Teacher")
academy/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,0,0,0
access_academy_courses,access_academy_courses,model_academy_courses,,1,0,0,0
讓我們也添加視圖橄镜,這樣我們就可以看到和編輯一個課程的老師:
academy/views.xml
</field>
</record>
<record id="action_academy_courses" model="ir.actions.act_window">
<field name="name">Academy courses</field>
<field name="res_model">academy.courses</field>
</record>
<record id="academy_course_search" model="ir.ui.view">
<field name="name">Academy courses: search</field>
<field name="model">academy.courses</field>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="teacher_id"/>
</search>
</field>
</record>
<record id="academy_course_list" model="ir.ui.view">
<field name="name">Academy courses: list</field>
<field name="model">academy.courses</field>
<field name="arch" type="xml">
<tree string="Courses">
<field name="name"/>
<field name="teacher_id"/>
</tree>
</field>
</record>
<record id="academy_course_form" model="ir.ui.view">
<field name="name">Academy courses: form</field>
<field name="model">academy.courses</field>
<field name="arch" type="xml">
<form>
<sheet>
<label for="name"/>
<field name="name"/>
<label for="teacher_id"/>
<field name="teacher_id"/>
</sheet>
</form>
</field>
</record>
<menuitem sequence="0" id="menu_academy" name="Academy"/>
<menuitem id="menu_academy_content" parent="menu_academy"
name="Academy Content"/>
<menuitem id="menu_academy_content_courses"
parent="menu_academy_content"
action="action_academy_courses"/>
<menuitem id="menu_academy_content_teachers"
parent="menu_academy_content" action="action_academy_teachers"/>
還應(yīng)該有可能直接從教師的網(wǎng)頁中創(chuàng)建新的課程偎快,或者看到他們教的所有課程,所以增加 the inverse relationship
到 教師 模型:
academy/models.py
name = fields.Char()
biography = fields.Html()
course_ids = fields.One2many('academy.courses', 'teacher_id', string="Courses")
class Courses(models.Model):
_name = 'academy.courses'
academy/views.xml
<form>
<sheet>
<label for="name"/> <field name="name"/>
<label for="biography"/>
<field name="biography"/>
<field name="course_ids">
<tree string="Courses" editable="bottom">
<field name="name"/>
</tree>
</field>
</sheet>
</form>
</field>
討論與通知
Odoo 提供技術(shù)的模式洽胶,不直接滿足業(yè)務(wù)需要而增加的能力滨砍,業(yè)務(wù)對象,而不必手動建立妖异。
其中之一是 Chatter 系統(tǒng)惋戏,Odoo 的電子郵件和通訊系統(tǒng),可以添加通知和討論線程模型他膳。該模型簡單地 _inherit
mail.thread
, 并添加 message_ids
字段以其窗體視圖顯示討論線程响逢。討論線程是記錄的。
對于我們的研究院棕孙,有意義的討論課程舔亭,以處理如調(diào)度變化或教師和助理之間的討論:
academy/models.py
class Courses(models.Model):
_name = 'academy.courses'
_inherit = 'mail.thread'
name = fields.Char()
teacher_id = fields.Many2one('academy.teachers', string="Teacher")
academy/views.xml
<label for="teacher_id"/>
<field name="teacher_id"/>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
在每個課程形態(tài)的底部些膨,現(xiàn)在有一個討論帖為系統(tǒng)留言,跟隨或不跟隨鏈接到特定的用戶討論課程的可能性钦铺。
銷售課程
Odoo 還提供商業(yè)模式允許使用或選擇在業(yè)務(wù)需求更直接订雾。比如說 website_sale
模塊建立了一個基于產(chǎn)品在 Odoo 系統(tǒng)電子商務(wù)網(wǎng)站。我們可以很容易地通過我們的課程課程訂閱特定種類的產(chǎn)品銷售矛洞。
而不是以前的經(jīng)典繼承洼哎,這意味著取代我們的 course 由 產(chǎn)品 模型,并在延伸產(chǎn)品(添加任何我們需要它)沼本。
首先噩峦,我們需要添加一個依賴于 website_sale
所以我們得到這兩種產(chǎn)品 (通過 sale
) 和電子商務(wù)接口:
academy/manifest.py
'version': '0.1',
# 這一個需要正確工作的模塊
'depends': ['website_sale'],
# 總是加載
'data': [
重啟 Odoo,更新你的模塊抽兆,現(xiàn)在有一個 店 部分網(wǎng)站识补,列出了一些預(yù)填充(通過實(shí)證數(shù)據(jù))的產(chǎn)品。
第二步是替換 courses 模型通過 product.template
, 為課程添加一個新的產(chǎn)品類別:
academy/manifest.py
'security/ir.model.access.csv',
'templates.xml',
'views.xml',
'data.xml',
],
# 只有在示范模式
'demo': [
academy/data.xml
<odoo>
<record model="product.public.category" id="category_courses">
<field name="name">Courses</field>
<field name="parent_id" ref="website_sale.categ_others"/>
</record>
</odoo>
academy/demo.xml
<field name="name">Lester Vaughn</field>
</record>
<record id="course0" model="product.template">
<field name="name">Course 0</field>
<field name="teacher_id" ref="padilla"/>
<field name="public_categ_ids" eval="[(4, ref('academy.category_courses'), False)]"/>
<field name="website_published">True</field>
<field name="list_price" type="float">0</field>
<field name="type">service</field>
</record>
<record id="course1" model="product.template">
<field name="name">Course 1</field>
<field name="teacher_id" ref="padilla"/>
<field name="public_categ_ids" eval="[(4, ref('academy.category_courses'), False)]"/>
<field name="website_published">True</field>
<field name="list_price" type="float">0</field>
<field name="type">service</field>
</record>
<record id="course2" model="product.template">
<field name="name">Course 2</field>
<field name="teacher_id" ref="vaughn"/>
<field name="public_categ_ids" eval="[(4, ref('academy.category_courses'), False)]"/>
<field name="website_published">True</field>
<field name="list_price" type="float">0</field>
<field name="type">service</field>
</record>
</odoo>
academy/models.py
name = fields.Char()
biography = fields.Html()
course_ids = fields.One2many('product.template', 'teacher_id', string="Courses")
class Courses(models.Model):
_inherit = 'product.template'
teacher_id = fields.Many2one('academy.teachers', string="Teacher")
academy/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,0,0,0
academy/views.xml
</field>
</record>
<menuitem sequence="0" id="menu_academy" name="Academy"/>
<menuitem id="menu_academy_content" parent="menu_academy"
name="Academy Content"/>
<menuitem id="menu_academy_content_teachers"
parent="menu_academy_content"
action="action_academy_teachers"/>
這個安裝辫红,現(xiàn)在幾門課程在 店是可用的凭涂,盡管他們可能要找。
Note
- 在地方擴(kuò)展模型, it's
inherited
不給它一個新的_name
-
product.template
已經(jīng)使用了討論系統(tǒng)贴妻,所以我們可以從我們的擴(kuò)展模型中刪除它 - 我們創(chuàng)造了我們的課程导盅, 發(fā)布 默認(rèn)情況下可以看到無需登錄
改變現(xiàn)有識圖
到目前為止,我們已經(jīng)簡要地看到:
- 創(chuàng)建新的模型
- 創(chuàng)建新的視圖
- 創(chuàng)建新的記錄
- 變更已存在的模型
我們離開與現(xiàn)有的記錄和改變現(xiàn)有的意見揍瑟。我們會在 店 頁。
看來改變是通過創(chuàng)建 extension 視圖乍炉,并應(yīng)用上的獨(dú)到的見解和改變它绢片。這些更改視圖可以添加或刪除,而不修改原始的岛琼,使它更容易嘗試的東西了底循,滾動的變化。
由于我們的課程是免費(fèi)的槐瑞,沒有任何理由在店內(nèi)展示他們的價格熙涤,所以我們將改變觀點(diǎn),并隱藏價格困檩,如果它是 0祠挫。第一個任務(wù)是找出哪些視圖顯示的價格,這可以通過 定制?HTML編輯器 讓我們讀參與渲染一個頁面的各種模板悼沿。通過幾個等舔,“產(chǎn)品項(xiàng)目”看起來可能是罪魁禍?zhǔn)住?/p>
改變視圖架構(gòu)是在 3 個步驟中完成的:
- 創(chuàng)建新的視圖
- 擴(kuò)展視圖修改設(shè)置的新觀點(diǎn)的
inherit_id
的修改視圖的外部標(biāo)識 - 在該體系結(jié)構(gòu)中,使用
XPath
標(biāo)簽來選擇和改變從修改的視圖元素
academy/templates.xml
<div class="oe_structure"/>
</t>
</template>
<template id="product_item_hide_no_price" inherit_id="website_sale.products_item">
<xpath expr="http://div[hasclass('product_price')]/b" position="attributes">
<attribute name="t-if">product.price > 0</attribute>
</xpath>
</template>
<!-- <template id="object"> -->
<!-- <h1><t t-esc="object.display_name"/></h1> -->
<!-- <dl> -->
我們將改變的第二件事是制作欄可見默認(rèn)產(chǎn)品類別: 定制?產(chǎn)品類別 讓你切換一個樹的產(chǎn)品類別(用于過濾的主要顯示)和關(guān)閉糟趾。
這是通過 customize_show
和 active
領(lǐng)域延伸擴(kuò)展模板:模板(如我們剛剛創(chuàng)建的)可以 customize_show=True慌植。這個選擇將顯示在 定制 菜單復(fù)選框甚牲,允許管理員來激活或禁用它們(容易地定制自己的網(wǎng)站頁面)。
我們只需要修改 產(chǎn)品類別 記錄并設(shè)置其默認(rèn) active="True":
academy/templates.xml
</xpath>
</template>
<record id="website_sale.products_categories" model="ir.ui.view">
<field name="active" eval="True"/>
</record>
<!-- <template id="object"> -->
<!-- <h1><t t-esc="object.display_name"/></h1> -->
<!-- <dl> -->
有了這個蝶柿,當(dāng) Academy 模塊被安裝丈钙,這個 產(chǎn)品分類 欄將自動被啟用時。