This is the documentation for older versions of Odoo (formerly OpenERP).

See the new Odoo user documentation.

See the new Odoo technical documentation.

YAML 数据序列化

YAML 是 human-readable 可读的数据序列化格式 概念源于 C, Perl, Python, 主意来自 XML 和电子邮件的数据格式. YAML stands for YAML Ain't Markup Language (yes, that's a recursive acronym). YAML 用于 OpenERP 数据格式 as of OpenERP 6.0, 有以下优点:

  • 作为当前的 XML 格式的一个用户友善的备选格式.

  • 在相同的系统模块中进行数据的装载,测试集成.

  • 内建与 OpenERP 以便开发复杂的 Python 测试.

  • 方便非开发人员写功能测试.

下面是一个 XML 记录和 YAML 记录的比较.

首先,XML 记录使用当前的 XML 序列化格式: (参阅 previous section )

<!--
    Resource: sale.order
-->

<record id="order" model="sale.order">
  <field name="shop_id" ref="shop"/>
  <field model="product.pricelist" name="pricelist_id" search="[]"/>
  <field name="user_id" ref="base.user_root"/>
  <field model="res.partner" name="partner_id" search="[]"/>
  <field model="res.partner.address" name="partner_invoice_id search="[]"/>
  <field model="res.partner.address" name="partner_shipping_id" search="[]"/>
  <field model="res.partner.address" name="partner_order_id" search="[]"/>
</record>

<!--
      Resource: sale.order.line
-->

<record id="line" model="sale.order.line">
  <field name="order_id" ref="order"/>
  <field name="name">New server config + material</field>
  <field name="price_unit">123</field>
</record>

<record id="line1" model="sale.order.line">
  <field name="order_id" ref="order"/>
  <field name="name">[PC1] Basic PC</field>
  <field name="price_unit">450</field>
</record>

YAML 记录

#<!--
#       Resource: sale.order
#   -->


-
 !record {model: sale.order, id: sale_order_so4}:
   amount_total: 3263.0
   amount_untaxed: 3263.0
   create_date: '2010-04-06 10:45:14'
   date_order: '2010-04-06'
   invoice_quantity: order
   name: SO001
   order_line:
     - company_id: base.main_company
       name: New server config + material
       order_id: sale_order_so4
       price_unit: 123.0
     - company_id: base.main_company
       name: '[PC1] Basic PC'
       order_id: sale_order_so4
       price_unit: 450.0
   order_policy: manual
   partner_id: base.res_partner_agrolait
   partner_invoice_id: base.main_address
   partner_order_id: base.main_address
   partner_shipping_id: base.main_address
   picking_policy: direct
   pricelist_id: product.list0
   shop_id: sale.shop

YAML Tags

data

  • Tag: data

  • 必选属性: None

  • 可选属性: noupdate : 0 | 1

  • 子节点标签:

    • menuitem

    • record

    • workflow

    • delete

    • act_window

    • assert

    • 报告

    • function

    • ir_set

  • 样例:

    -
      !context
       noupdate: 0
    

record

  • 标签: record

  • 必选属性:
    • model

  • 可选属性: noupdate : 0 | 1

  • 子节点标签:
    • field

  • 可选属性:
    • id

    • forcreate

    • context

  • 样例:

    -
      !record {model: sale.order, id: order}:
         name: "[PC1] Basic PC"
         amount_total: 3263.0
         type_ids:
           - project_tt_specification
           - project_tt_development
           - project_tt_testing
         order_line:
             - name: New server config
                order_id: sale_order_so4
             - name: '[PC1] Basic PC'
                order_id: sale_order_so4
    

field

  • 标签: field

  • 必选属性:
    • name

  • 可选属性:
    • type

    • ref

    • eval

    • domain

    • search

    • model

    • use

  • 子节点标签:
    • text node

  • 样例:

    -price_unit: 450
    -product_id: product.product_product_pc1
    

workflow

  • 标签: workflow

  • 必选属性:
    • model

    • action

  • 可选属性:
    • uid

    • ref

  • 子节点标签:
    • value

  • 样例:

    -
     !workflow {action: invoice_open, model: account.invoice}:
      - eval: "obj(ref('test_order_1')).invoice_ids[0].id"
        model: sale.order
      - model: account.account
        search: [('type', '=', 'cash')]
    

function

  • 标签: function

  • 必选属性:
    • model

    • name

  • 可选属性:
    • id

    • eval

  • 子节点标签:
    • value

    • function

  • 样例:

    -
     !function {model: account.invoice, name: pay_and_reconcile}:
      -eval: "[obj(ref('test_order_1')).id]"
       model: sale.order
    

value

  • 标签: value

  • 必选属性: None

  • 可选属性:
    • model

    • search

    • eval

  • 子节点标签: None

  • 样例:

    -eval: "[obj(ref('test_order_1')).id]"
     model: sale.order
    

act_window

  • 标签: act_window

  • 必选属性:
    • id

    • name

    • res_model

  • 可选属性:

    • domain

    • src_model

    • context

    • view

    • view_id

    • view_type

    • view_mode

    • multi

    • target

    • key2

    • groups

  • 子节点标签: None

  • 样例:

    -
      !act_window {target: new,
      res_model: wizard.ir.model.menu.create,
      id:act_menu_create, name: Create Menu}
    

报告

  • 标签: report

  • 必选属性:
    • string

    • model

    • name

  • 可选属性:

    • id

    • 报告

    • multi

    • menu

    • keyword

    • rml

    • sxw

    • xml

    • xsl

    • auto

    • header

    • attachment

    • attachment_use

    • groups

  • 子节点标签: None

  • 样例:

    -
      !report {string: Technical guide,
       auto: False, model: ir.module.module,
       id: ir_module_reference_print,
       rml: base/module/report/ir_module_reference.rml,
       name: ir.module.reference}
    

ir_set

  • 标签: ir_set

  • 必选属性: None

  • 可选属性: None

  • 子节点标签:
    • field

  • 样例:

    -
     !ir_set:
     args: "[]"
     name: account.seller.costs
     value: tax_seller
    

python

  • 标签: Python

  • 必选属性:
    • model

  • 可选属性: None

  • 子节点标签: None

  • 样例:

    Python code
    

delete

  • 标签: delete

  • 必选属性:
    • model

  • 可选属性:
    • id

    • search

  • 子节点标签: None

  • 样例:

    -
      !delete {model: ir.actions, search: "[(model,like,auction.)]"}
    

assert

  • 标签: assert

  • 必选属性:
    • model

  • 可选属性:
    • id

    • search

    • string

  • 子节点标签:
    • test

  • 样例:

    -
      !assert {model: sale.order,
       id: test_order, string: order in progress}:
         - state == "progress"
    

test

  • 标签: test

  • 必选属性:
    • expr

  • 可选属性: None

  • 子节点标签:
    • text node

  • 样例:

    - picking_ids[0].state == "done"
    

url

  • 标签: url

  • 必选属性: -

  • 可选属性: -

  • 子节点标签: -

  • 样例: -

写一个 YAML 测试

注解

参考第三部分 3   YAML 自动测试指南 自动化YAML测试指南

手工写
  • 记录的 CRUD

  • 工作流过渡

  • 段言 (像在 XML 中的语句)

  • 纯 Python 代码

使用 base_module_record(er)

  • 生成带有 record 和 workflow 的 YAML 文件

/doc_static/6.0/_images/record_object.png
  • 用 assertions / Python 代码更新这个 YAML

警告

重要

yaml 的结构采用(像 Python)缩进, 每一个 child 标签(sub-tag) 相对于父标签进行缩进.

Field Tag

  • text
    • 用双引号在前面或后面包含输入的文字.

      Ex: name: "[PC1] Basic PC"

  • integer and float

    Ex: price_unit: 450 Ex: amount_total: 3263.0

  • boolean

    active: 1

  • datetime

    date_start: str(time.localtime()[0] - 1) + -08-07

  • selection
    • 给出一个缩写

      Ex: title: M.

  • many2one
    • 如果它是 res_id 的引用, 指向 res_id

      Ex: user_id: base.user_root

    • 如果它的值是基于搜索条目,那么指定 model 到搜索条目

      Ex: object_id: !ref {model: ir.model, search: "[('model','=','crm.claim')]”}

  • one2many
    • start each record in one2many field on a new line with a space and a hyphen

      Ex: order_line: name: New server config order_id: sale_order_so4 ......

      name: '[PC1] Basic PC' order_id: sale_order_so4 ......

  • many2many
    • 用每一个 many2many 字段,以空格和连字符开始

      Ex: type_ids: - project_tt_specification ** **- project_tt_development - project_tt_testing

Value tag

  • 如果Tag能被评估(like res_id is available), 像下面一样写 value tag :

    - !function {model: account.invoice, name: pay_and_reconcile}: - eval: "obj(ref('test_order_1')).amount_total" model: sale.order

    这会捕获一个 'sale.order' 记录的 'amount_total' 值伴随 res_id 'test_order_1'

  • 如果值是在一些基于条目的模块上被搜索, 那么就像下面一样写 value tag :

    - !function {model: account.invoice, name: pay_and_reconcile}: - model: account.account search: "[('type', '=', 'cash')]" 这将抓取所有 account.account 记录类型等于 'cash'

Test Tag

  • 直接指定测试

    Ex: - picking_ids[0].state == "done" - state == "manual"

comment

#<!-- Resource: sale.order -->

Asserts and Python code

为了创建一个发票,python 代码应该这样写:

-
!python {model: account.invoice}: |

self.action_move_create(cr, uid, [ref("invoice1")])

发票必须在 draft 状态:

-
!assert {model: account.invoice , id: invoice1, string: "the invoice is now in Draft state"}:

- state == "draft"

测试所有在树形数据结构的账户, 我们写下面的 python 代码:

-
!python {model: account.account}:

ids = self.search(cr, uid, [])

accounts_list = self.read(cr, uid, ids['parent_id','parent_left','parent_right'])

accounts = dict((x['id'], x) for x in accounts_list)

log("Testing parent structure for %d accounts", len(accounts_list))

for a in accounts_list:
if a['parent_id']:

assert a['parent_left']>accounts[a['parent_id'][0]]['parent_left']

assert a['parent_right']<accounts[a['parent_id'][0]]['parent_right']

assert a['parent_left']<a['parent_right']

for a2 in accounts_list:

assert not ((a2['parent_right']>a['parent_left'])and

(a2['parent_left']<a['parent_left'])and

(a2['parent_right']<a['parent_right']))

if a2['parent_id']==a['id']:

assert(a2['parent_left']>a['parent_left'])and(a2['parent_right']<a['parent_right'])

运行测试

  • 以扩展名 '.yml' 保存文件

  • 添加 yaml 文件到 'demo_xml' 下

  • 以参数 '--log-level=test' 运行服务器