odoo V10开发文档(入门:建立网站)

1.创建模块

odoo提供scaffold命令用来快速创建模块:

odoo scaffold <module name> <module directory>

2.模块控制器

打开module name文件夹,如mymodules/academy ,编辑controllers/controllers.py,在init.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"

保存,重启odoo,此处如果模块文件夹不是默认,执行的时候需要指定addon目录(当前路径相对路径或绝对路径):

odoo --addons-path addons,mymodules

在开发者模式下更新应用列表,在设置-应用右上角搜索栏中搜索academy(需去掉应用过滤)安装
,安装完成后在浏览器输入 localhost:8069/academy/academy即可看到简单的hello word页面了

3.自定义模板

odoo自己开发了一套QWeb模板引擎,修改controller让它加载自定义模板:

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"],
    })

然后编辑template.xml,此模板在manifest.py中配置到data中加载:

<odoo>
<data>
    <template id="index">
        <title>Academy</title>
        <t t-foreach="teachers" t-as="teacher">
          <p><t t-esc="teacher"/></p>
        </t>
    </template>
</data>
</odoo>

此模板将teachers循环输出,重启odoo服务,找到academy点击升级,刷新localhost:8069/academy/academy页面会显示新的内容了

4.数据保存

  • 模型定义

编辑models/models.py

class Teachers(models.Model):
_name = 'academy.teachers'

name = fields.Char()

编辑security/ir.model.access.csv并加入manifest.py

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

此处即设置数据为对所有用户只读

所有xml和csv文件都需要在manifest内进行引入,controller和module文件需要在init内进入导入

  • 测试数据,编辑demo.xml
<odoo>
    <data>
        <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>
    </data>
</odoo>
  • 数据读取
    修改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([])
        })

修改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>

重启odoo服务,升级academy(升级时会自动创建数据表,导入测试数据),重新打开localhost:8069/academy/academy 此时展现的数据就是数据库读取出来的了

5.模块用于网站

odoo提供了一个用于建立网站的模块,接下来测试academy用于网站中

  • 在manifest中将模块定义为website:
    'depends': ['website']
  • 在controller中指定为website:
class Academy(http.Controller):
    @http.route('/academy/academy/', auth='public', website=True)
  • 在模板中添加website layout
<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>

重启odoo并更新模块(加载template和manifest),重新进入academy页面,页面已经用了网站前端的布局

6.链接和路由

在controller中通过route()装饰器来处理请求,除了标准的URL之外,还可以接受参数型url,例:

 @http.route('/academy/<name>/', auth='public', website=True)
    def teacher(self, name):
        return '<h1>{}</h1>'.format(name)
        
  @http.route('/academy/<int:id>/', auth='public', website=True)
    def teacher_id(self, id):
        return '<h1>{} ({})</h1>'.format(id, type(id).__name__)

重启odoo,浏览器进入academy/test和academy/1 所显示出来的页面是不一样的,odoo还支持使用数据模型做参数

#controllers.py
@http.route('/academy/<model("academy.teachers"):teacher>/', auth='public', website=True)
    def teacher(self, teacher):
        return http.request.render('academy.biography', {
            'person': teacher
        })

#template.xml
<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>

重启odoo并升级模块,输入academy/1 查看效果

7.使模块在菜单栏可见

默认情况下,新建的模块对用户来说是不可见的,需要创建一个菜单用户才能在页面中看到

#view.xml
 <!-- 默认列表 -->
    <record id="action_academy_teachers" model="ir.actions.act_window">
    <field name="name">Academy teachers</field>
    <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"/>
  <menuitem id="menu_academy_content_teachers"
            parent="menu_academy_content"
            action="action_academy_teachers"/>

重启odoo并更新模块,菜单会有academy入口了,默认会展现一个列表,点进去可编辑

8.数据模型相互关联

建立一个课程表模型,每个课程需要有一个老师,课程表就需要有一个老师ID的字段来进行关联,需要建立一个一对多的关系

#models.py 添加
class Teachers(models.Model):
    _name = 'academy.teachers'

    name = fields.Char()
    biography = fields.Html()

    course_ids = fields.One2many('academy.courses', 'teacher_id', string="Courses")
    
class Courses(models.Model):
    _name = 'academy.courses'

    name = fields.Char()
    teacher_id = fields.Many2one('academy.teachers', string="Teacher")

#ir.model.access.csv 添加
access_academy_courses,access_academy_courses,model_academy_courses,,1,0,0,0

#view.xml 更新
<!-- 单条数据视图 -->
   <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"/>

          <field name="course_ids">
            <tree string="Courses" editable="bottom">
              <field name="name"/>
            </tree>
          </field>
        </sheet>
      </form>
    </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"/>

此时重启odoo并更新模块,进入academy,点击菜单的course,看看会有什么

9.odoo聊天系统

odoo自带聊天系统,只需要在models里引入mail.thread,添加messageid到表单中即可,下面为课程添加讨论功能

#__manifest__.py 
'depends': ['base','mail'],

#models.py
class Courses(models.Model):
    _name = 'academy.courses'
    _inherit = 'mail.thread'

    name = fields.Char()
    teacher_id = fields.Many2one('academy.teachers', string="Teacher")

#views.xml
<form>
    <sheet>
      <label for="name"/>
      <field name="name"/>
      <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>

10.odoo交易功能

odoo提供了website_sales的交易模块,只需要做简单的修改就可以实现商品发布(安装电子商务模块)

#__manifest__.py
'depends': ['website_sale'],

'data': [
        'security/ir.model.access.csv',
        'views/views.xml',
        'views/templates.xml',
        'data/data.xml' #此处为新增
    ],
    
#data/data.xml 新增
<odoo>
<data>
  <record model="product.public.category" id="category_courses">
    <field name="name">Courses</field>
    <field name="parent_id" ref=""/>
  </record>
</data>
</odoo>

#demo.xml
<record id="padilla" model="academy.teachers">
        <field name="name">老师1号</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>

#models.py
class Teachers(models.Model):
    _name = 'academy.teachers'

    name = fields.Char()
    biography = fields.Html()

    course_ids = fields.One2many('product.template', 'teacher_id', string="Courses")

class Courses(models.Model):
    _inherit = 'product.template'

    name = fields.Char()
    teacher_id = fields.Many2one('academy.teachers', string="Teacher")
    
#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

#views.xml 去掉前面步骤创建的课程视图
<!-- 单条数据视图 -->=
<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"/>

      <field name="course_ids">
        <tree string="Courses" editable="bottom">
          <field name="name"/>
        </tree>
      </field>
    </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_teachers"
        parent="menu_academy_content"
        />

重启odoo,打开网站-商店,发现有添加的课程了


内容发布自http://www.dingyii.cn,转载请注明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容