跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

  1. 主页
  2. 版块
  3. Odoo 开发与实施交流
  4. Default_get函数为什么会执行两次?

Default_get函数为什么会执行两次?

已定时 已固定 已锁定 已移动 Odoo 开发与实施交流
6 帖子 4 发布者 5.3k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • J 离线
    J 离线
    jerry79
    写于 最后由 编辑
    #1

    python

    <br />def default_get(self, cr, uid, fields_list, context=None):<br />&nbsp; &nbsp; if &#039;name&#039; in fields_list:<br />&nbsp; &nbsp; &nbsp; &nbsp; trial_account = self.pool.get(&#039;ir.sequence&#039;).get(cr, uid, &#039;web.account.trial&#039;)<br />&nbsp; &nbsp; &nbsp; &nbsp; res.update({&#039;name&#039;: trial_account})<br />def button_confirm(self, cr, uid, ids, context=None):<br />&nbsp; &nbsp; return True<br />
    


    XML

    <br />…………<br /> &lt;field name=&quot;name&quot; placeholder=&quot;请在此填入账户名称&quot;/&gt;<br /> &lt;footer&gt;<br />&nbsp; &nbsp; &nbsp; &lt;button name=&quot;button_confirm&quot; type=&quot;object&quot; string=&quot;确认&quot; class=&quot;oe_highlight&quot;/&gt;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or<br />&nbsp; &nbsp; &nbsp; &lt;button string=&quot;Cancel&quot; class=&quot;oe_link&quot; special=&quot;cancel&quot; /&gt;<br /> &lt;/footer&gt;<br />
    


    新建对话框的时候,name默认获得一个新的帐号,如T00001,是一个自增帐号。
    现在的问题是,新建对话框后,name显示T00001,但是点击“确认”按钮后,name就变成T00002了,保存在数据库中的也是T00002,T00001只是显示一下,没有被保存住。
    测试了一下,发现新建的时候,default_get运行了一次,点击确认关闭对话框的时候,default_get又运行了一次,或以再次抓取了一个新的name。
    请问为什么default_get会运行两次呢?或者有什么办法解决这个问题?
    谢谢!

    1 条回复 最后回复
    0
    • W 离线
      W 离线
      wangbuke
      写于 最后由 编辑
      #2

      以代码回复:

      第一次 调用 default_get 是,当你点击 button new 的时候:

      参见view_form.js

      <br />&nbsp; &nbsp; on_button_new: function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; var self = this;<br />&nbsp; &nbsp; &nbsp; &nbsp; this.to_edit_mode();<br />&nbsp; &nbsp; &nbsp; &nbsp; return $.when(this.has_been_loaded).then(function() {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (self.can_be_discarded()) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self.load_defaults();<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; });<br />&nbsp; &nbsp; },<br /><br /><br />&nbsp; &nbsp; load_defaults: function () {<br />&nbsp; &nbsp; &nbsp; &nbsp; var self = this;<br />&nbsp; &nbsp; &nbsp; &nbsp; var keys = _.keys(this.fields_view.fields);<br />&nbsp; &nbsp; &nbsp; &nbsp; if (keys.length) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this.dataset.default_get(keys).then(function(r) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.trigger(&#039;load_record&#039;, r);<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; return self.trigger(&#039;load_record&#039;, {});<br />&nbsp; &nbsp; },<br /><br />
      



      var keys = _.keys(this.fields_view.fields) 这样会去取所有字段的默认值。

      第二次调用 default_get 是  orm.py  的 create 方法:

      <br />&nbsp; &nbsp; def create(self, cr, user, vals, context=None):<br />&quot;&quot;&quot;<br />&nbsp; &nbsp; &nbsp; &nbsp; vals = self._add_missing_default_values(cr, user, vals, context)<br />&quot;&quot;&quot;<br />
      



      那么我们来看一下 _add_missing_default_values 函数:

      <br />&nbsp; &nbsp; def _add_missing_default_values(self, cr, uid, values, context=None):<br />&nbsp; &nbsp; &nbsp; &nbsp; missing_defaults = &#91;]<br />&nbsp; &nbsp; &nbsp; &nbsp; avoid_tables = &#91;] # avoid overriding inherited values when parent is set<br />&nbsp; &nbsp; &nbsp; &nbsp; for tables, parent_field in self._inherits.items():<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if parent_field in values:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; avoid_tables.append(tables)<br />&nbsp; &nbsp; &nbsp; &nbsp; for field in self._columns.keys():<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not field in values:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; missing_defaults.append(field)<br />&nbsp; &nbsp; &nbsp; &nbsp; for field in self._inherit_fields.keys():<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (field not in values) and (self._inherit_fields[field][0] not in avoid_tables):<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; missing_defaults.append(field)<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; if len(missing_defaults):<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # override defaults with the provided values, never allow the other way around<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaults = self.default_get(cr, uid, missing_defaults, context)<br /><br />。。。。。。<br />
      



      以上,missing_defaults 就是需要获取默认值的列,那么为什么有些字段会重复取值呢, 原因是 create 方法参数 vals 中仅仅保持了 form view 中定义的字段,而第一次取的字段值,可能会因为 form view 中没有对于字段,而被丢弃了。所以,在 create 方法中,会认为该字段没有赋值,因此又会添加到 missing_defaults  再取一次默认值。


      原因找到了,解决方法就不难了吧。

      其中一种BT的方法是,在 FORM VIEW 定义一个 field invisable = True 的字段,隐藏带上来。

      1 条回复 最后回复
      0
      • JoshuaJ 离线
        JoshuaJ 离线
        Joshua 管理员
        写于 最后由 编辑
        #3

        [quote author=wangbuke link=topic=9918.msg19783#msg19783 date=1377068877]
        ......
        那么为什么有些字段会重复取值呢, 原因是 create 方法参数 vals 中仅仅保持了 form view 中定义的字段,而第一次取的字段值,可能会因为 form view 中没有对于字段,而被丢弃了。所以,在 create 方法中,会认为该字段没有赋值,因此又会添加到 missing_defaults  再取一次默认值。
        [/quote]

        感谢buke的精彩回复,这里我举个例子说一下为什么form view的字段会被丢弃的原因:
        例如字段定义[b]readonly[/b]了,那样就会出现上述buke所描述的情形。

        待lz分析下自己问题的出现原因。

        【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

        1 条回复 最后回复
        0
        • wjfonhandW 离线
          wjfonhandW 离线
          wjfonhand
          写于 最后由 编辑
          #4

          name已经定义了,第二次不该调用

          GoodERP -- Odoo China fork

          1 条回复 最后回复
          0
          • J 离线
            J 离线
            jerry79
            写于 最后由 编辑
            #5

            非常感谢buke的详细解释,也感谢Joshua的解决方案,将name字段的readonly属性取消后,确实没有问题了。
            另外,上周没来得及上论坛,我自己用了一个笨方法解决问题,就是用sql去查询数据库中已有的name的最大值,如查出来是T00010, +1后在存回去。这样虽然form view字段被丢弃,但是因为是从数据库查询,所以不管default_get执行多少次都不会有问题。

            1 条回复 最后回复
            0

            • 登录

            • 没有帐号? 注册

            • 登录或注册以进行搜索。
            • 第一个帖子
              最后一个帖子
            0
            • 版块
            • 标签
            • 热门
            • 用户
            • 群组