翼度科技»论坛 编程开发 python 查看内容

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

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
一些用户界面

数据文件 (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.
动作可以通过三种方式触发 :

  • 点击菜单项目(链接接到指定动作)
  • 点击视图按钮(如果与action关联)
  • 对象的上下文action
本章仅涵盖第一种情况。 我们Real Estate例子中,希望将一个菜单连接到 estate.property model, 以便创建一个新记录。 action可以视为菜单和model之间的链接
test.model 的基本action:
  1. <record id="test_model_action" model="ir.actions.act_window">
  2.     <field name="name">Test action</field>
  3.     <field name="res_model">test.model</field>
  4.     <field name="view_mode">tree,form</field>
  5. </record>
复制代码

  • id  外部标识。它可以用于引用记录(不需要知道其在数据库中的标识符)。
  • model  ir.actions.act_window (Window Actions (ir.actions.act_window))的一个固定值
  • name action名称
  • res_model action应用的范围。
  • view_mode 可获取的视图。本例中为列表(树)和表格视图。
odoo中到处都可以找到例子,但是这个 简单action的好例子。关注XML 数据文件结构,因为你在后续的练习中会用到。
  1. <?xml version="1.0"?>
  2. <odoo>
  3.     <record id="crm_lost_reason_view_search" model="ir.ui.view">
  4.         <field name="name">crm.lost.reason.view.search</field>
  5.         <field name="model">crm.lost.reason</field>
  6.         <field name="arch" type="xml">
  7.             <search string="Search Opportunities">
  8. <menuitem id="test_menu_root" name="Test">
  9.     <menuitem id="test_first_level_menu" name="First Level">
  10.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  11.     </menuitem>
  12. </menuitem><field name="name"/>
  13. <menuitem id="test_menu_root" name="Test">
  14.     <menuitem id="test_first_level_menu" name="First Level">
  15.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  16.     </menuitem>
  17. </menuitem><filter string="Include archived" name="archived" domain="['|', ('active', '=', True), ('active', '=', False)]"/>
  18. <menuitem id="test_menu_root" name="Test">
  19.     <menuitem id="test_first_level_menu" name="First Level">
  20.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  21.     </menuitem>
  22. </menuitem><separator/>
  23. <menuitem id="test_menu_root" name="Test">
  24.     <menuitem id="test_first_level_menu" name="First Level">
  25.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  26.     </menuitem>
  27. </menuitem><filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
  28.             </search>
  29.         </field>
  30.     </record>
  31.     <record id="crm_lost_reason_view_form" model="ir.ui.view">
  32.         <field name="name">crm.lost.reason.form</field>
  33.         <field name="model">crm.lost.reason</field>
  34.         <field name="arch" type="xml">
  35.             <form string="Lost Reason">
  36. <menuitem id="test_menu_root" name="Test">
  37.     <menuitem id="test_first_level_menu" name="First Level">
  38.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  39.     </menuitem>
  40. </menuitem><sheet>
  41. <menuitem id="test_menu_root" name="Test">
  42.     <menuitem id="test_first_level_menu" name="First Level">
  43.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  44.     </menuitem>
  45. </menuitem>   
  46. <menuitem id="test_menu_root" name="Test">
  47.     <menuitem id="test_first_level_menu" name="First Level">
  48.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  49.     </menuitem>
  50. </menuitem>        <button name="action_lost_leads" type="object"
  51. <menuitem id="test_menu_root" name="Test">
  52.     <menuitem id="test_first_level_menu" name="First Level">
  53.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  54.     </menuitem>
  55. </menuitem>             icon="fa-star">
  56. <menuitem id="test_menu_root" name="Test">
  57.     <menuitem id="test_first_level_menu" name="First Level">
  58.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  59.     </menuitem>
  60. </menuitem>            
  61. <menuitem id="test_menu_root" name="Test">
  62.     <menuitem id="test_first_level_menu" name="First Level">
  63.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  64.     </menuitem>
  65. </menuitem><menuitem id="test_menu_root" name="Test">
  66.     <menuitem id="test_first_level_menu" name="First Level">
  67.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  68.     </menuitem>
  69. </menuitem><field name="leads_count" />
  70. <menuitem id="test_menu_root" name="Test">
  71.     <menuitem id="test_first_level_menu" name="First Level">
  72.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  73.     </menuitem>
  74. </menuitem><menuitem id="test_menu_root" name="Test">
  75.     <menuitem id="test_first_level_menu" name="First Level">
  76.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  77.     </menuitem>
  78. </menuitem> Leads
  79. <menuitem id="test_menu_root" name="Test">
  80.     <menuitem id="test_first_level_menu" name="First Level">
  81.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  82.     </menuitem>
  83. </menuitem>            
  84. <menuitem id="test_menu_root" name="Test">
  85.     <menuitem id="test_first_level_menu" name="First Level">
  86.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  87.     </menuitem>
  88. </menuitem>        </button>
  89. <menuitem id="test_menu_root" name="Test">
  90.     <menuitem id="test_first_level_menu" name="First Level">
  91.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  92.     </menuitem>
  93. </menuitem>   
  94. <menuitem id="test_menu_root" name="Test">
  95.     <menuitem id="test_first_level_menu" name="First Level">
  96.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  97.     </menuitem>
  98. </menuitem>    <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
  99. <menuitem id="test_menu_root" name="Test">
  100.     <menuitem id="test_first_level_menu" name="First Level">
  101.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  102.     </menuitem>
  103. </menuitem>   
  104. <menuitem id="test_menu_root" name="Test">
  105.     <menuitem id="test_first_level_menu" name="First Level">
  106.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  107.     </menuitem>
  108. </menuitem>        
  109. <menuitem id="test_menu_root" name="Test">
  110.     <menuitem id="test_first_level_menu" name="First Level">
  111.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  112.     </menuitem>
  113. </menuitem>            <label for="name"/>
  114. <menuitem id="test_menu_root" name="Test">
  115.     <menuitem id="test_first_level_menu" name="First Level">
  116.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  117.     </menuitem>
  118. </menuitem>        
  119. <menuitem id="test_menu_root" name="Test">
  120.     <menuitem id="test_first_level_menu" name="First Level">
  121.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  122.     </menuitem>
  123. </menuitem>        <h1 >
  124. <menuitem id="test_menu_root" name="Test">
  125.     <menuitem id="test_first_level_menu" name="First Level">
  126.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  127.     </menuitem>
  128. </menuitem>            <field name="name" />
  129. <menuitem id="test_menu_root" name="Test">
  130.     <menuitem id="test_first_level_menu" name="First Level">
  131.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  132.     </menuitem>
  133. </menuitem>        </h1>
  134. <menuitem id="test_menu_root" name="Test">
  135.     <menuitem id="test_first_level_menu" name="First Level">
  136.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  137.     </menuitem>
  138. </menuitem>        <field name="active" invisible="1"/>
  139. <menuitem id="test_menu_root" name="Test">
  140.     <menuitem id="test_first_level_menu" name="First Level">
  141.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  142.     </menuitem>
  143. </menuitem>   
  144. <menuitem id="test_menu_root" name="Test">
  145.     <menuitem id="test_first_level_menu" name="First Level">
  146.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  147.     </menuitem>
  148. </menuitem></sheet>
  149.             </form>
  150.         </field>
  151.     </record>
  152.     <record id="crm_lost_reason_view_tree" model="ir.ui.view">
  153.         <field name="name">crm.lost.reason.tree</field>
  154.         <field name="model">crm.lost.reason</field>
  155.         <field name="arch" type="xml">
  156.             <tree string="Channel" editable="bottom">
  157. <menuitem id="test_menu_root" name="Test">
  158.     <menuitem id="test_first_level_menu" name="First Level">
  159.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  160.     </menuitem>
  161. </menuitem><field name="name"/>
  162.             </tree>
  163.         </field>
  164.     </record>
  165.    
  166.     <record id="crm_lost_reason_action" model="ir.actions.act_window">
  167.         <field name="name">Lost Reasons</field>
  168.         <field name="res_model">crm.lost.reason</field>
  169.         <field name="view_mode">tree,form</field>
  170.         <field name="help" type="html">
  171.           <p >
  172.             Define a new lost reason
  173.           </p><p>
  174.             Use lost reasons to explain why an opportunity is lost.
  175.           </p><p>
  176.             Some examples of lost reasons: "We don't have people/skill", "Price too high"
  177.           </p>
  178.         </field>
  179.     </record>
  180.     <record id="menu_crm_lost_reason" model="ir.ui.menu">
  181.         <field name="action" ref="crm.crm_lost_reason_action"/>
  182.     </record>
  183. </odoo>
复制代码
练习

为 estate.property model  创建action。
在适当的位置(本例中为odoo14/custom/estate/models/views)创建 estate_property_views.xml
  1. <?xml version="1.0"?>
  2. <odoo>
  3.     <record id="link_estate_property_action" model="ir.actions.act_window">
  4.         <field name="name">Properties</field>
  5.         <field name="res_model">estate.property</field>
  6.         <field name="view_mode">tree,form</field>
  7.     </record>
  8. </odoo>
复制代码
修改odoo14/custom/estate/__manifest__.py
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. {
  4.     'name': 'estate',
  5.     'depends': ['base'],
  6.     'data':['security/ir.model.access.csv',
  7.             'views/estate_property_views.xml'
  8.             ]
  9. }
复制代码
重启服务并观察文件加载日志。
菜单(Menus)

参考: 和本主题关联文档可以查看Shortcuts.
为了减少菜单(ir.ui.menu)定义和链接到对应action的复杂性,我们可以使用 shortcut
test_model_action 一个的基础菜单:
  1. [/code]test_model_menu_action 菜单被链接到 test_model_action ,action链接到model test.model。正如前面所述, action可以看做是菜单和model之间的连接。
  2. [b]注意:这里的id的值和action的值不能设置成一样,否则会报错。[/b]
  3. 然而,菜单总是遵循一种体系结构,实际上有三个层次的菜单:
  4. [list=1]
  5. [*]根菜单,显示在App切换器中(Odoo社区版切换器是一个下拉菜单)
  6. [*]第一级菜单,显示在顶部栏中
  7. [*]动作菜单
  8. [/list][align=center][/align]
  9. [align=center][/align]
  10. 最容易的方式是在XML文件中定义结构来创建菜单。
  11. 为 test_model_action 定义的一个基础菜单结构:
  12. [code]<menuitem id="test_menu_root" name="Test">
  13.     <menuitem id="test_first_level_menu" name="First Level">
  14.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  15.     </menuitem>
  16. </menuitem>
复制代码
第三级菜单的名称,直接从action获取,即为action属性值
练习

添加菜单
在合适的目录(本例中为odoo14/custom/estate/models/views)创建 estate_menus.xml 文件
  1. <menuitem id="test_menu_root" name="Test">
  2.     <menuitem id="test_first_level_menu" name="First Level">
  3.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  4.     </menuitem>
  5. </menuitem><menuitem id="test_menu_root" name="Test">
  6.     <menuitem id="test_first_level_menu" name="First Level">
  7.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  8.     </menuitem>
  9. </menuitem>   
复制代码
修改odoo14/custom/estate/__manifest__.py
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. {
  4.     'name': 'estate',
  5.     'depends': ['base'],
  6.     'data':['security/ir.model.access.csv',
  7.             'views/estate_property_views.xml',
  8.             'views/estate_menus.xml'
  9.             ]
  10. }
复制代码
重启odoo服务,查看效果

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

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

  • 某些字段有默认值
  • 某些字段只读
  • 当记录重复时,某些字段不能被拷贝
在我们的房产业务案例中,我们希望::

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

在进一步进行视图设计之前,让我们回到模型定义。我们看到一些属性,如required=True,会影响数据库中的表模式。其他属性也将影响视图或提供默认值。
练习 -- 添加一些属性到字段。
查找一些合适的属性 (查看字段) 来:

  • 设置售价为只读
  • 阻止复制可用日期和售价
修改  odoo14\custom\estate\models\estate_property.py 中EstateProperty类属性expected_price,selling_price的值如下:
  1. expected_price = fields.Float('expected price', digits=(8, 2),  required=True)
  2. 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对象自身为入参并返回一个值的函数:
  1. name = fields.Char(default="Unknown")
  2. last_seen = fields.Datetime("Last Seen", default=lambda self: fields.Datetime.now())
复制代码
例中name字段默认值为‘Unknown’,而last_seen 字段默认值为当前时间
练习 -- 设置默认值
添加适当的默认值:

  • 卧室数量默认值为 2
  • 可用日期默认为3个月内
修改  odoo14\custom\estate\models\estate_property.py 中EstateProperty类属性bedrooms,selling_price的值如下:
  1. bedrooms = fields.Integer(default=2)
  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.py 中EstateProperty类,增加active属性
  1. 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.py 中EstateProperty类,修改active字段,增加state字段
  1.     active = fields.Boolean('Active', default=True, invisible=True) # 注意:实践发现,invisible字段不起作用    state = fields.Selection(        string='State',        selection=[('New','New'),<menuitem id="test_menu_root" name="Test">
  2.     <menuitem id="test_first_level_menu" name="First Level">
  3.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  4.     </menuitem>
  5. </menuitem>   ('Offer Received','Offer Received'),<menuitem id="test_menu_root" name="Test">
  6.     <menuitem id="test_first_level_menu" name="First Level">
  7.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  8.     </menuitem>
  9. </menuitem>   ('Offer Accepted', 'Offer Accepted'),<menuitem id="test_menu_root" name="Test">
  10.     <menuitem id="test_first_level_menu" name="First Level">
  11.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  12.     </menuitem>
  13. </menuitem>   ('Sold','Sold'),<menuitem id="test_menu_root" name="Test">
  14.     <menuitem id="test_first_level_menu" name="First Level">
  15.         <menuitem id="test_model_menu_action" action="test_model_action"/>
  16.     </menuitem>
  17. </menuitem>   ('Canceled', 'Canceled')],        copy=False    )
复制代码
重启服务,验证效果

来源:https://www.cnblogs.com/shouke/p/17253318.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具