用Odoo创建一个网站

原贴地址:https://www.odoo.com/documentation/10.0/howtos/website.html

声明:这篇指导假设你有python的知识并安装了Odoo,请注意文件的目录结构,本文的目录结构与原文不同。

创建一个基础模块

在Odoo中,工作是通过创建的模型展开的。

模型决定了Odoo的行为。也许是通过添加新的行为,亦或许是通过已经存在的(通过其他模型安装的行为)

Odoo的scaffold能够初始化一个基础模块。是你可以快速的开始。

$ ./odoo-bin scaffold Academy my-modules

这将自动创建my-modules模块目录,目录里面有一个academy。如果你愿意,这个目录可以是一个存在的目录,但是子目录的名字必须的惟一的。

一个样例

我们有一个安装好的模块,尽管他并不能做什么:

1.打开Odoo的服务器,用下面的方式

$ ./odoo-bin --addons-path addons,my-modules

--addon-path是包含模块的路径。addons是必须包含的,里面有启动文件,my-modules是我们刚才安装的。

2.浏览器进入http://localhost:8069

3.进入Settings-Modules-Modules

4.在右上角删除过滤器(应该说的是搜索框里的api x)并搜索academy

5.点击academy模块的安装按钮

这个过程大家应该很熟悉了,很多地方都讲过,他说的有点复杂,我在多说一点,如果没有发现模块,打开开发模式,然后切回到setting(应用)页面,左边有更新应用列表。

浏览器

控制器终端浏览器请求并返回数据。

#添加一个简单的控制器并确保他被引入__init__.py(这样Odoo才能找到他)

academy/controllers/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):

这里我怀疑是新旧版本的问题,作为初学者,我还是愿意遵循他创建文件夹的结构,把这个东西写在controller文件夹里。

重启服务器ctrl+c两次。

在浏览器里输入localhost:8069/academy/academy/

hello,world!

模板

用python生成HTML并不是很理想。

一般的解决方案是模板。pseudo-documents有占位符和展示逻辑: Odoo允许任何Python模板系统,但是提供他自己的QWeb模板系统,整合了他自己的特点。

创建一个模板并确保模板文件在__manifest__.py中注册(如果写在了),并转换控制器使用我们的模板。

academy/controllers/controllers.py

class Academy(http.Controller):
    @http.route('/academy/academy/', auth='public')
    def index(self, **kw):
        return http.request.render('academy.index', {
            'teachers': ["C"],
        })

#     @http.route('/academy/academy/objects/', auth='public')
#     def list(self, **kw):

academy/views/templates.xml

<odoo>
    <data>
        <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)遍历了所有的teachers(通过模板的上下文(这里就是controller))。

最终重启Odoo并升级模块数据。

Odoo能够重启并同时创建模块。

在浏览器里输入localhost:8069/academy/academy/

Dinana Padilla

Jody Caaoll

Lester Yaughn


在Odoo上存储数据

Odoo的模型映射数据库

在之前的部分我们只是用python的代码展示了一个字符串列表。这并不允许改变或维持贮存,所以我们要将他存入数据库。

定义数据模型

定义一个teacher模型,并确保他被__init__.py(models内的)引入,并正确加载。

academy/models/models.py

from odoo import models, fields, api

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

    name = fields.Char()

接着为模型安装基础的访问控制,并添加他们的manifest:

academy/__manifest__.py

    # always loaded
    'data': [
        'security/ir.model.access.csv',
        'templates.xml',
    ],
    # only loaded in demonstration mode

academy/security/ir.model.acess.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

这里简单的给了所有用户(group_id:id)读权限(perm_read)

数据文件(XML或者CSV)必须被添加在模块的manifest中,Python文件(模型或者控制器)不用,但是Python文件必须引入在__init__.py中(直接或者间接)

管理员用户通过权限来控制,他们能进入所哟逇模型甚至没有给权限的

数据样例

第二步是为系统添加一些数据样例,这样测试起来很容易。通过添加demo数据可以很容做到。demo.xml也必须链接到manifest:

academy/demo/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>

数据文件可用于演示和非演示数据。演示数据只在演示模式被加载,可以用作测试和演示,非演示数据总是被加载,并在系统初始化的时候就启用了。

在这种情况下我们使用演示数据,因为一个系统的真实的用户会想要输入或导出他们自己的教师列表,而这个列表只用于测试。

访问数据

最后一步就是改变模型和模板来使用我们的演示数据。

1.从数据库获取记录来替代掉已经存在的静态的列表

2.由于search()返回一个记录的集合,匹配过滤器("所有的记录"在合理),改变模板或者打印每一个教师的name

academy/controllers/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/views/template.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"> -->

重启服务器并更新模块(为了更新manifest和模板,并加载演示数据),接着去http://localhost:8069/academy/academy/。页面将会有些不同:名字被加上数字前缀(数据库对教师的识别)。

看起来名字没有变化,我虽然不知道数据是什么时候进去的,但是这次名字确实是从数据库取出来的。如果没有,卸载模块重新安装。


网站支持

Odoo绑定一个模块专注于建站。

目前为止我们直接使用了控制器,但是Odoo8添加了更深层的继承和一个其他服务。(比如,默认样式,主题)用过网站模块。

1.添加website作为academy的依赖

academy/__manifest__.py

    'version': '0.1',

    # any module necessary for this one to work correctly
    'depends': ['website'],

    # always loaded
    'data': [

2.在控制器中添加website=True标记,在请求对象时这里添加了一些新的变量并允许使用网络布局。

academy/controllers/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', {

3.在模板中使用网络布局

academy/views/template.xml

<odoo>
    <data>
        <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"> -->

在重启服务器升级模块以后(为了更新manifest和模板)访问http://localhost:8069/academy/academy 你会得到一个看起来更舒服的页面,有标题logo和一些内置页面元素(menu,footer)

图我就不贴了,比教程贴的那个好看多了。

这个网站的布局同样提供支持:点击登录(右上角),填充凭证(admin/admin默认)来登录。(我的已经是登录状态了)

你现在在Odoo的后台:管理员特有界面。现在点击网站menu里的元素(左上角)

我们回到网站,作为一个管理员,我们能访问网站提供的高级编辑特征:

1.模板代码编辑(Customize-HTML Editor)你可以看见当前页面使用的所有的模板。

2.编辑按钮在左上角,装换位编辑模式,这样富文本编辑器就可以用了。

3.大量的其他特性比如移动端或者SEO

这块自己摸索下吧,介绍的应该是8,我用的11,不太一样

URL和路由

控制器方法通过route()装饰器把路由联系在一起,route()装饰器包含一个字符串和多个定制行为或者安全的属性。

我们看到的字符串就是URL,然而路由的字符串能使用转换样式匹配其中一小部分,匹配URL和和那些可用的变量,比如我们创建一个新的控制器方法来设置部分的路径并打印他。

academy/controllers/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/Alics和http://localhost:8069/academy/Bob/来查看不同。

顾名思义,转换样式并不只是做提取,他们同样做验证和转换,所以我们可以换个新的控制器只接收整型数据:

academy/controllers/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,就明确了为什么之前是字符串而现在是数字,再尝试下http://localhost:8069/academy/Carol,你会发现页面找不到了,因为Carol不是个整数,路由忽略了它,并且没有路由能被找到。

Odoo提供了一个添加转换器叫做model,当你给定id的时候他能直接转换为记录。容我们用他来为教师传记创建页面吧。

academy/controllers/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/views/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> -->

接着改变模型的列表来链接新的控制器。

这里,通过http://localhost:8069/academy/jody-carroll-2/访问新的页面。

academy/views/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并升级模块,然后你能开到每一个教师的页面,作为一个联系,试着在一个教师的页面新建一个区域来写传记,然后去第二个,你会发现,你的传记被所有教师分享了,是因为这个区域是添加在模板里的,这个模板是被分享的。当一个页面被修改,所有的页面都将被修改。

这里做一个理解,因为我刚看的时候也没看懂如果新建一个区域,直到我翻译到后面关于t-field属性可修改这里的时候。因为我是管理员,所以网站的最上方会多一个条,条的最右边有一个Edit,点击以后进入编辑模式,t-esc属性是不可编辑的,t-field属性的可编辑是从这里编辑。

新建的一个区域是指:进入编辑模式以后,最左边的一列框,可以通过手动添加进页面的。这个区域的内容是所有同类型页面共享的。

字段编辑

数据需要被保存在指定的记录中,我们来为我们的教师添加传记字段:

academy/models/models.py

    _name = 'academy.teachers'

    name = fields.Char()
    biography = fields.Html()
academy/views/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并更新视图,重新加载教师页面,这个字段是看不见的因为他没有包含内容。

作为记录的字段,模板能使用特殊的t-field指令,这个指令允许通过字段指定接口编辑来自网站的字段内容。更改person

模板为t-field。这里注意<t>标签不支持t-field 一定会报错的。

academy/views/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并升级模块,在编辑模式下,你能看见教师的名字下方,有一个占位符和一个新的块状区域。输入的内容将会保存在相符的教师传记的biography字段中,并指向这个教师。

教师名字同样是可以编辑的,保存后,修改过的名字在第一页也是可以看见的。

t-field字段同样可以通过额外的字段格式化选项。比如我们展示了教师记录的更新日期:

academy/views/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/views/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/views/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>


管理和erp整合

Odoo管理端简介

Odoo管理端非常容易看到。通过网站支持部分部分。我们可以回到管理端通过导航中的Administrator-Administrator(如果登出了需要登录)

odoo的后台概念结构很简单:

1.导航,一个树结构(导航下有子导航)。导航没有子映射。。。

2.动作,动作有多种类型链接,报告,Odoo执行的代码或者数据显示。数据显示动作被称作window action,并根据视图集合告知Odoo要展示给定的模型。

3.视图有一个类型,一个与其对应的分类(列表,图形,日历),和一种模型被展示在视图里的结构。

在Odoo的管理端编辑

一般来说,一个Odoo模型本质上对用户是不可见的。想看见他必须通过动作使他生效,它本身必须可以触及,一般在导航里。

我们来在模型中创建一个导航:

academy/__manifest__.py

    'data': [
        'security/ir.model.access.csv',
        'views/templates.xml',
        'views/views.xml',
    ],
    # only loaded in demonstration mode
    'demo': [

academy/views/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/在左上角会出现导航Academy,默认被选作第一导航,会打开教师列表。在列表中,可以创建新的教师记录,并通过记录视图转换到表单。

如果没有关于如何呈现一个记录(视图)的定义,Odoo将会自动创建一个基础的。在我看来,他适用于列表视图(只是展示教师的名字),但是在表单视图中HTML的biography字段和name字段一起被展示,并没有给出足够的空间。让我们用视图定义一个客户表单视图,来更好的展示和编辑教师的字段:

academy/views/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"/>

模型间的关联

我们可以看到一对基础字段直接存进记录。这里有大量的基础字段。第二类字段是关系型的,用于记录间的链接(在模型中或者通过模型)。

在示例中,我们创造了courses模型,每一个课程都需要有一个teacher字段,链接一个单一的教师记录,但是一个教师可以教多门课。

academy/models/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/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"/>

他需要在教师的页面也能直接创造新的课程,或者看到所有他要教授的课程,所以在教师模型中添加转换关系。

academy/models/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/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提供技术模型,虽然不能直接满足业务需要,但是并不需要亲手创建他们就可以扩展业务对象的能力。

其中有一个叫做Chatter的系统,拥有Odoo的email和信息系统的部分功能,能够将通知和讨论功能添加到任何模型中。模型只要继承 mail.thread,并在表单视图中添加message_ids字段来显示讨论线程。讨论线程是预记录。

对于我们的academy,允许通过讨论的方针来调整教师和助手的课程变化或者商讨。

academy/models/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/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>

在每一个课程表格的下方,有一个讨论线程,可能为系统的用户留下信息,跟随或者不跟随的讨论链接到指定的课程。

卖课

Odoo允许提供业务模型,允许更直接的使用或者选择业务需求。比如website_sale模块,安装了一个e-commerce网站,基于Odoo系统上的产品。我们可以容易的 通过把我们的课程制作为产品,实现课程的订阅。

相比于之前传统的继承,这意味着要通过产品模型替换我们的课程模型,并扩展产品的原状(为他添加一切我们需要的东西)。

首先我们需要添加一个依赖:website_sale,所以我们有products(通过sale)和ecommerce接口:

academy/__manifest__.py

    'version': '0.1',

    # any module necessary for this one to work correctly
    'depends': ['website_sale'],

    # always loaded
    'data': [

重启Odoo,升级你的模型,现在你的网站是一个商店了,排列了大量的预填充的产品(通过展示数据)。

第二部是替换课程模型通过product.template,并为课程添加行的产品分类:

academy/__manifest__.py

        'security/ir.model.access.csv',
        'views/templates.xml',
        'views/views.xml',
        'views/data.xml',
    ],
    # only loaded in demonstration mode
    'demo': [

academy/views/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/views/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/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/views.py

    </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"/>

随着安装,一些课程现在在商店中可以使用了,尽管你可能还需要寻找。

想要扩展一个模型的原型,继承他但是不要给他新的_name

product.template已经使用了讨论系统,所以我们可以在扩展模块中删除它

我们创建了我们的课程就像默认被展示一样,所以不需要登录你也可以看到。

注意

首先,views.py中要多删一些东西,因为我们把course类的_name删了,所以找不到academy.courses。所以views中有一大段model为academy.coursses是要注释掉的。

然后还会报错:

External ID not found in the system: %s' % xmlid

所以删掉

    <field name="parent_id" ref="website_sale.categ_others"/>

转换存在的视图

我们有一个简介要看:

新模型的创建

新视图的创建

新纪录的创建

转换存在的模型

我们要保留现有记录的改变和现有视图的改变,我们现在要在商店页面做这些。

视图的转变通过创建扩展视图完成,扩展视图被应用在原始视图上,并改变了他。这些转换的视图可以被添加也可以被删除,都不会改变原有的视图,这样会更容易的实验和回滚。

自从我们的课程免费,没有理由在商店页面展示他的加个,所以我们想要转换视图并隐藏价格(如果是0)。第一个工作是找到哪个视图展示了价格,可以通过Customize-HTML Editor来完成它。编辑器是用来读取包含给定页面中的各种的模板。通过他们中的一部分,‘产品’看起来像个罪犯。

转换视图结构分3步:

1.创建新视图

2.通过设置视图的inherit_id来改变视图扩展id的方式改变视图。

3.在结构中,从被改变的视图中使用xpath便签来选择和改变元素

academy/views/templates.xml

                <div class="oe_structure"/>
            </t>
        </template>

        <template id="product_item_hide_no_price" inherit_id="website_sale.products_item">
            <xpath expr="//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> -->

我们要做的第二个改变时使产品分类条默认:Customize-Product分类让我们触发一个产品分类树的开关(被用于主显示的过滤)

这部分可以通过扩展模板的customize_show和active字段完成:一个扩展模板(就像我们刚创建的一样)能够被customize_show=True。这个选择将在定制菜单中展示视图,定制菜单有个checkbox框,允许管理员激活或者关闭他们(很容易设定他们的网站页面)

我们简单的需要改变产品分类记录并设置他的默认值为active=True:

academy/views/template.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> -->

有了它,在academy模块安装的时候,产品分类条将字段激活。


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值