百木园-与人分享,
就是让自己快乐。

odoo 开发入门教程系列-一些用户界面

一些用户界面

数据文件 (XML)

参考: 该主题关联文档可以查看Data Files.

上一章,我们通过CSV文件添加了数据。当需要添加数据格式简单时,用CSV格式还是很方便的,当数据格式更复杂时(比如视图架构或者一个邮件模板),我们使用XML格式。比如包含HTML tags的 help field。虽然可以通过CSV文件加载这样的数据,但是使用XML更方便。

类似CSV文件,XML文件也必须按约定添加到合适的目录,并在 __manifest__.py中进行定义。数据文件中的内容也是在模块安装或者更新时按序加载。因此,对CSV文件所做的所有说明对XML文件都适用。当数据链接到视图时,我们将它们添加到views文件夹中

本章,我们将通过XML文件加载我们第一个action和菜单。Actions 和菜单为数据库中的标准记录。

注解:

当程序很注重性能时,CSV格式优先于XML格式。这是因为,在odoo中加载CSV文件比加载XML文件更快。

odoo中,用户接口(action,菜单和视图)大部分是通过创建和组装XML文件中的记录来定义的。常见的模式为 菜单> action > 视图。为了访问记录,用户在几个菜单级中导航。最深层是触发打开记录列表的action。

操作(Actions)

参考: 主题相关文档可以查看 Actions.

动作可以通过三种方式触发 :

  1. 点击菜单项目(链接接到指定动作)
  2. 点击视图按钮(如果与action关联)
  3. 对象的上下文action

本章仅涵盖第一种情况。 我们Real Estate例子中,希望将一个菜单连接到 estate.property model, 以便创建一个新记录。 action可以视为菜单和model之间的链接

test.model 的基本action:

<record id=\"test_model_action\" model=\"ir.actions.act_window\">
    <field name=\"name\">Test action</field>
    <field name=\"res_model\">test.model</field>
    <field name=\"view_mode\">tree,form</field>
</record>
  • id 外部标识。它可以用于引用记录(不需要知道其在数据库中的标识符)。
  • model ir.actions.act_window (Window Actions (ir.actions.act_window))的一个固定值
  • name action名称
  • res_model action应用的范围。
  • view_mode 可获取的视图。本例中为列表(树)和表格视图。

odoo中到处都可以找到例子,但是这个 简单action的好例子。关注XML 数据文件结构,因为你在后续的练习中会用到。

<?xml version=\"1.0\"?>
<odoo>
    <record id=\"crm_lost_reason_view_search\" model=\"ir.ui.view\">
        <field name=\"name\">crm.lost.reason.view.search</field>
        <field name=\"model\">crm.lost.reason</field>
        <field name=\"arch\" type=\"xml\">
            <search string=\"Search Opportunities\">
                <field name=\"name\"/>
                <filter string=\"Include archived\" name=\"archived\" domain=\"[\'|\', (\'active\', \'=\', True), (\'active\', \'=\', False)]\"/>
                <separator/>
                <filter string=\"Archived\" name=\"inactive\" domain=\"[(\'active\', \'=\', False)]\"/>
            </search>
        </field>
    </record>

    <record id=\"crm_lost_reason_view_form\" model=\"ir.ui.view\">
        <field name=\"name\">crm.lost.reason.form</field>
        <field name=\"model\">crm.lost.reason</field>
        <field name=\"arch\" type=\"xml\">
            <form string=\"Lost Reason\">
                <sheet>
                    <div class=\"oe_button_box\" name=\"button_box\">
                        <button name=\"action_lost_leads\" type=\"object\"
                            class=\"oe_stat_button\" icon=\"fa-star\">
                            <div class=\"o_stat_info\">
                                <field name=\"leads_count\" class=\"o_stat_value\"/>
                                <span class=\"o_stat_text\"> Leads</span>
                            </div>
                        </button>
                    </div>
                    <widget name=\"web_ribbon\" title=\"Archived\" bg_color=\"bg-danger\" attrs=\"{\'invisible\': [(\'active\', \'=\', True)]}\"/>
                    <div class=\"oe_title\">
                        <div class=\"oe_edit_only\">
                            <label for=\"name\"/>
                        </div>
                        <h1 class=\"mb32\">
                            <field name=\"name\" class=\"mb16\"/>
                        </h1>
                        <field name=\"active\" invisible=\"1\"/>
                    </div>
                </sheet>
            </form>
        </field>
    </record>

    <record id=\"crm_lost_reason_view_tree\" model=\"ir.ui.view\">
        <field name=\"name\">crm.lost.reason.tree</field>
        <field name=\"model\">crm.lost.reason</field>
        <field name=\"arch\" type=\"xml\">
            <tree string=\"Channel\" editable=\"bottom\">
                <field name=\"name\"/>
            </tree>
        </field>
    </record>

    <!-- Configuration/Lead & Opportunities/Lost Reasons Menu -->
    <record id=\"crm_lost_reason_action\" model=\"ir.actions.act_window\">
        <field name=\"name\">Lost Reasons</field>
        <field name=\"res_model\">crm.lost.reason</field>
        <field name=\"view_mode\">tree,form</field>
        <field name=\"help\" type=\"html\">
          <p class=\"o_view_nocontent_smiling_face\">
            Define a new lost reason
          </p><p>
            Use lost reasons to explain why an opportunity is lost.
          </p><p>
            Some examples of lost reasons: \"We don\'t have people/skill\", \"Price too high\"
          </p>
        </field>
    </record>

    <record id=\"menu_crm_lost_reason\" model=\"ir.ui.menu\">
        <field name=\"action\" ref=\"crm.crm_lost_reason_action\"/>
    </record>
</odoo>

练习

estate.property model 创建action。

在适当的位置(本例中为odoo14/custom/estate/models/views)创建 estate_property_views.xml

<?xml version=\"1.0\"?>
<odoo>
    <record id=\"link_estate_property_action\" model=\"ir.actions.act_window\">
        <field name=\"name\">Properties</field>
        <field name=\"res_model\">estate.property</field>
        <field name=\"view_mode\">tree,form</field>
    </record>
</odoo>

修改odoo14/custom/estate/__manifest__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
    \'name\': \'estate\',
    \'depends\': [\'base\'],
    \'data\':[\'security/ir.model.access.csv\',
            \'views/estate_property_views.xml\'
            ]
}

重启服务并观察文件加载日志。

菜单(Menus)

参考: 和本主题关联文档可以查看Shortcuts.

为了减少菜单(ir.ui.menu)定义和链接到对应action的复杂性,我们可以使用 shortcut

test_model_action 一个的基础菜单:

<menuitem id=\"test_model_menu_action\" action=\"test_model_action\"/>

test_model_menu_action 菜单被链接到 test_model_actionaction链接到model test.model。正如前面所述, action可以看做是菜单和model之间的连接。

注意:这里的id的值和action的值不能设置成一样,否则会报错。

然而,菜单总是遵循一种体系结构,实际上有三个层次的菜单:

  1. 根菜单,显示在App切换器中(Odoo社区版切换器是一个下拉菜单)
  2. 第一级菜单,显示在顶部栏中
  3. 动作菜单

最容易的方式是在XML文件中定义结构来创建菜单。

test_model_action 定义的一个基础菜单结构:

<menuitem id=\"test_menu_root\" name=\"Test\">
    <menuitem id=\"test_first_level_menu\" name=\"First Level\">
        <menuitem id=\"test_model_menu_action\" action=\"test_model_action\"/>
    </menuitem>
</menuitem>

第三级菜单的名称,直接从action获取,即为action属性值

练习

添加菜单

在合适的目录(本例中为odoo14/custom/estate/models/views)创建 estate_menus.xml 文件

<?xml version=\"1.0\"?>
<odoo>
    <menuitem id=\"test_menu_root\" name=\"Test\">
        <menuitem id=\"test_first_level_menu\" name=\"First Level\">
            <menuitem id=\"estate_property_menu_action\" action=\"link_estate_property_action\"/>
        </menuitem>
    </menuitem>
</odoo>

修改odoo14/custom/estate/__manifest__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
    \'name\': \'estate\',
    \'depends\': [\'base\'],
    \'data\':[\'security/ir.model.access.csv\',
            \'views/estate_property_views.xml\',
            \'views/estate_menus.xml\'
            ]
}

重启odoo服务,查看效果

字段,属性和视图(Fields, Attributes And View)

到目前为止,我们只对房产广告使用了通用视图,但在大多数情况下,我们希望对视图进行微调。Odoo有许多微调方式,但通常第一步是确保:

  • 某些字段有默认值
  • 某些字段只读
  • 当记录重复时,某些字段不能被拷贝

在我们的房产业务案例中,我们希望::

  • 售价只读(往后将自动填充)
  • 当记录重复时,可用日期和售价不能被拷贝
  • 卧室数量应该默认为2
  • 默认可用日期应该为3个月

一些新属性

在进一步进行视图设计之前,让我们回到模型定义。我们看到一些属性,如required=True,会影响数据库中的表模式。其他属性也将影响视图或提供默认值。

练习 -- 添加一些属性到字段。

查找一些合适的属性 (查看字段) 来:

  • 设置售价为只读
  • 阻止复制可用日期和售价

修改 odoo14\\custom\\estate\\models\\estate_property.pyEstateProperty类属性expected_priceselling_price的值如下:

expected_price = fields.Float(\'expected price\', digits=(8, 2),  required=True) 
selling_price = fields.Float(\'selling price\', digits=(8, 2), readonly=True, copy=False)

重启服务和并刷新浏览器界面,我们可以看到无法设置任何售价。复制记录时,可用日期应为空。

预期效果可参考该动画连接:https://www.odoo.com/documentation/14.0/zh_CN/_images/attribute_and_default.gif

默认值

可以为任何字段设置默认值。字段定义中,添加 default=X, 其中的X 可以是Python文本值(boolean, integer, float, string) ,也可以是一个以model对象自身为入参并返回一个值的函数:

name = fields.Char(default=\"Unknown\")
last_seen = fields.Datetime(\"Last Seen\", default=lambda self: fields.Datetime.now())

例中name字段默认值为‘Unknown’,而last_seen 字段默认值为当前时间

练习 -- 设置默认值

添加适当的默认值:

  • 卧室数量默认值为 2
  • 可用日期默认为3个月内

修改 odoo14\\custom\\estate\\models\\estate_property.pyEstateProperty类属性bedroomsselling_price的值如下:

bedrooms = fields.Integer(default=2)
date_availability = fields.Datetime(\'Availability Date\', copy=False, default= lambda self: fields.Datetime.today())

重启服务和并刷新浏览器界面验证

保留字段

参考: 主题相关文档可参考 保留字段名称.

odoo为预定义行为保留了一些字段名称。当需要相关行为时,需要在模型中定义这些保留字段。

练习 -- 添加active字段

添加一个 active 字段到estate.property 模型。

修改 odoo14\\custom\\estate\\models\\estate_property.pyEstateProperty类,增加active属性

active = fields.Boolean(\'Active\')

重启服务,刷新浏览器界面,新增一条记录,新增时勾选Active复选框,即active=True,验证效果。

预期效果可参考该动画链接:https://www.odoo.com/documentation/14.0/zh_CN/_images/inactive.gif

注意,已存在的记录的active字段默认值为False

练习--为active字段添加设置

active字段设置默认值

active 字段设置适当的属性值,让它不再出现在页面。

练习 -- 添加state字段

estate.property model添加state 字段(字段名可自定义),一个选择列表。可选值: New, Offer Received, Offer Accepted, SoldCanceled。必选字段,且不能被拷贝,默认值New

修改 odoo14\\custom\\estate\\models\\estate_property.pyEstateProperty类,修改active字段,增加state字段

    active = fields.Boolean(\'Active\', default=True, invisible=True) # 注意:实践发现,invisible字段不起作用
    state = fields.Selection(
        string=\'State\',
        selection=[(\'New\',\'New\'),
                   (\'Offer Received\',\'Offer Received\'),
                   (\'Offer Accepted\', \'Offer Accepted\'),
                   (\'Sold\',\'Sold\'),
                   (\'Canceled\', \'Canceled\')],
        copy=False
    )

重启服务,验证效果

作者:授客

微信/QQ:1033553122

全国软件测试QQ交流群:7156436


Git地址:https://gitee.com/ishouke

友情提示:限于时间仓促,文中可能存在错误,欢迎指正、评论!

作者五行缺钱,如果觉得文章对您有帮助,请扫描下边的二维码打赏作者,金额随意,您的支持将是我继续创作的源动力,打赏后如有任何疑问,请联系我!!!

           微信打赏                       
支付宝打赏                  全国软件测试交流QQ群  
odoo 开发入门教程系列-一些用户界面
      odoo 开发入门教程系列-一些用户界面
       odoo 开发入门教程系列-一些用户界面


来源:https://www.cnblogs.com/shouke/p/17253318.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » odoo 开发入门教程系列-一些用户界面

相关推荐

  • 暂无文章