odoo10 行表创建新数据时默认取值

 

场景:

  1. 用户在填写一些行表的数据时,可能会有很多的必输字段,然后需要填写的内容和第一行的内容差不多,所以就会存在在创建的时候就自动默认和第一行的内容相同这样的需求。

  2. 还有一种情况,是默认和头上的某个字段取值相同,直接带出的情况

思路 - 1:

行上的数据都是一张行表的数据,可以在界面上整个ids的字段上设置context,然后给需要默认带出的字段设置一个默认属性default,设置默认的取值方法

实现 - 1:

首先从界面开始,One2many的字段视图如下:

<page string="Detail">
    <field name="asset_equipment_detail_ids">
        <tree editable="bottom" create="1">
            <field name="asset_id"/>
            <field name="receive_time"/>
            <field name="return_time"/>
            <field name="duration_time" sum="Total Duration Time"/>
            <field name="note"/>
        </tree>
    </field>
</page>

ids字段加上一个context

<field name="asset_equipment_detail_ids" context="{'detail_data': asset_equipment_detail_ids}">

这里传的不是一个单单的字符串,它是一个数据集,记录着这个ids字段上的数据信息,会一并传给后台。


我们用

detail_obj = self.env.context.get('detail_data', False)

来获取前段传过来得到数据

这里就存在如下几种情况:

情况1:

新建一条数据,直接往行里面添加数据,这样获取的ids数据,第一次是空的列表,第二次就会是这样:

detail_obj
<type 'list'>: 
    [
        [0, False, {u'asset_id': 47185, u'receive_time': u'2019-11-08 15:33:37', u'note': False, u'return_time': u'2019-11-08 15:33:38', u'duration_time': 0}]
    ]

就能得到上一次填入的内容,在创建一行的话,就能得到的内容如下:

detail_obj
<type 'list'>: 
    [
        [0, False, {u'asset_id': 47185, u'receive_time': u'2019-11-08 15:33:37', u'note': False, u'return_time': u'2019-11-08 15:33:38', u'duration_time': 0}], 
        [0, False, {u'asset_id': 47186, u'receive_time': u'2019-11-08 15:33:37', u'note': False, u'return_time': u'2019-11-08 15:33:38', u'duration_time': 0}]
    ]

情况2:

这个情况我们是修改数据,在已有的数据行上编辑,新增。如果这时已经有一条数据了。情况就是这样的:

detail_obj
<type 'list'>: 
    [
        [4, 36, False]
    ]

如果有两条数据,情况就是这样的:

detail_obj
<type 'list'>: 
    [
        [4, 36, False], 
        [4, 37, False]
    ]

情况3:

在情况2的条件下,新建了一条数据,但是还没有保存的时候,情况是1和2的结合:

detail_obj
<type 'list'>: 
    [
        [4, 36, False], 
        [4, 37, False], 
        [0, False, {u'asset_id': 47186, u'receive_time': u'2019-11-06 12:25:32', u'note': False, u'return_time': u'2019-11-09 12:25:32', u'duration_time': 72}]
    ]

小总结 - 1:

已经保存的数据,只会记录数据的id,但是方法里同时传入的self里,就是模型对象。而临时添加的数据,类似于缓存的机制,会先记录,点击保存以后,在Many2one字段里面进行[0, false, {value}]的写操作。


所以,我们就可以拿到我们想要的数据,进行我们需要的需求设计。

  • 已存在的还是缓存的内容,可以通过列表的第二位,就是索引为1

  • 如果为False,就是新加的数据,如果不是False,就是已经存在的数据;通过self.browse(id)方法获取需要的数据(这里取得是第一行的数据)

    • self.browse(detail_obj[0][1]).某字段

总结 - 1:

最后的代码如下:

    def _get_first_receive_time(self):
      detail_obj = self.env.context.get('detail_data', False)
      if detail_obj:
          if not detail_obj[0][1]:
              return detail_obj[0][2].get('receive_time', '')
          return self.browse(detail_obj[0][1]).receive_time
​
    receive_time = fields.Datetime(string='Receive Time', required=True, default=lambda self: self._get_first_receive_time())

 

<page string="Detail">
    <field name="asset_equipment_detail_ids" options="{'no_edit_no_open':1}" context="{'detail_data': asset_equipment_detail_ids}" attrs="{'readonly':[('state','!=','created')]}">
        <tree editable="bottom" create="1">
            <field name="asset_id" options="{'no_create':True}"/>
            <field name="receive_time"/>
            <field name="return_time"/>
            <field name="duration_time" options="{'readonly_save':1}" sum="Total Duration Time"/>
            <field name="note"/>
        </tree>
    </field>
</page>

这样就能获取到行表的第一行数据,做到默认到处第一行的数据。

 

思路 - 2

需要什么,就获取什么,直接取头上的需要的字段,但是传值的方法就是直接通过context

实现 - 2

头行结构的数据,都会关联两张表,一般的xml文件的form视图都是这样构思的

<!-- 费用申请单form -->
<record id="view_form" model="ir.ui.view">
    <field name="name">xxx.form</field>
    <field name="model">model.name</field>
    <field name="arch" type="xml">
        <form dynamic_page_force_button="1">
            <header>
                ......
            </header>
            <sheet>
                <div class="oe_button_box" name="button_box" style="text-align:right">
                    ....
                </div>
                <group name="group_head" col="4">
                    <field name="date"/>
                    <field name="telephone"/>
                    <field name="requisition_amount"/>
                    <field name="budget_source"/>
                    <field name="reimbursable_amount"/>
                    <field name="start_date"/>
                    <field name="end_date"/>
                </group>
                <notebook>
                    <page string="Expense Details">
                        <field name="expense_requisition_line_ids" context="{'start_date': start_date, 'end_date': end_date, 'date': date}" attrs="{'readonly':[('state','!=','created')]}" options="{'no_edit_no_open':1}">
                            <tree editable="bottom" toolbar="1">
                                <field name="actual_amount" sum="Total Actual Amount"/>
                                <field name="currency_id" options="{'readonly_save':1}"/>
                                <field name="reimbursable_amount" sum="Total Reimbursable Amount"/>
                                <field name="note"/>
                            </tree>
                        </field>
                    </page>
                </notebook>
            </sheet>
        </form>
    </field>
</record>

sheet的group里面是头上的内容,notebook下的page,就是行表的内容。头表上一定有一个One2many的字段,关联行表,那个字段一般都是.._ids命名。使用field标签,对应上一对多的字段,标签之间包裹的就是行表的字段。

说到这里,我想表达的意思就是,想要在行上默认带出头上的字段,就要把头上的字段,对应传给头上的One2many字段,通过context。

注意例子中的ids字段expense_requisition_line_ids,context里面传的就是头上的start_dateend_date,我们在xml中将头上的字段传给了行,然后在模型中定义默认取值,就达到效果了。

# 开始日期
date_start = fields.Date(string='Start Date', default=lambda self:self.env.context.get('start_date',False))
# 结束日期
date_stop = fields.Date(string='End Date', default=lambda self:self.env.context.get('end_date',False))

将默认值,界面上,头的信息传给模型字段,就达到了默认的效果

总结 - 2

行上取头上的默认带出,相对于取同样的行上的字段要简单一些,不要考虑数据库中已经存在的行,以及界面的已经缓存了的数据的情况。当然,各尽其责,看需求是什么了。

 
原文地址:https://www.cnblogs.com/pywjh/p/12238140.html