0

在 OpenERP 中,我有 3 个模型,A、B 和 C。如果您从 A 的表单开始,有一个子 B 的树形列表。当您单击其中一个 B 子时,该表单有一个子 C 的树形列表。我需要将 C 孩子与父母 A 和 B 关联,但尽管 A 和 B 都有 many2one 字段,但他们只会将自己与 B 关联。我该如何强制这种关联?我查看了使用 active_id 和 default_get 的解决方案,但没有成功。上下文对象似乎对此很有用,但是当我从 A 向下钻取到 C 浏览表单时,我看不到使用两个父对象的 id 动态设置它的方法。我不明白为什么上下文通常不用于以这种方式保存上下文,就像在各种 Web 框架中一样。

澄清一下,当我编辑对象 A 并从它的编辑表单创建 B 的实例并从 B 的编辑表单创建 C 的实例时,如何使 C 与 A 和 B 关联?

我是否应该在 C 的 create 方法中使用子选择查询执行一个简单的更新来实现这一点,还是会破坏 ORM?

当我保存一个新的 C 实例(文档)时查看事务数据,我发现我需要的所有 id 都在事务中,但我不知道如何访问和操作我需要的值,例如

{
   "jsonrpc":"2.0",
   "method":"call",
   "params":{
      "model":"dbe.vendor",
      "method":"write",
      "args":[
         [
            3
         ],
         {
            "application":[
               [
                  4,
                  2,
                  false
               ],
               [
                  1,
                  21,
                  {
                     "documents":[
                        [
                           4,
                           37,
                           false
                        ],
                        [
                           4,
                           35,
                           false
                        ],
                        [
                           4,
                           46,
                           false
                        ],
                        [
                           4,
                           36,
                           false
                        ],
                        [
                           0,
                           false,
                           {
                              "state":"new",
                              "name":"order of precendence test",
                              "description":"TESTING",
                              "type_of":7,
                              "locked":false,
                              "note":false,
                              "datas":false,
                              "datas_fname":false,
                              "type":"binary",
                              "application_id":false,
                              "certification_id":false,
                              "vendor_id":3,
                              "message_follower_ids":false,
                              "message_ids":false
                           }
                        ]
                     ]
                  }
               ]
            ]
         }
      ],
      "kwargs":{
         "context":{
            "lang":"en_US",
            "tz":"EST",
            "uid":7
         }
      },
      "session_id":"303ae4c1bd9d49079c4efc9e06e0184f",
      "context":{
         "lang":"en_US",
         "tz":"EST",
         "uid":7
      }
   },
   "id":"r138"
}

注意:我手动插入了 vendor_id,因为它是必填字段,但它是我想要自动填充的字段。

4

2 回答 2

0

也许我对 OpenERP 的了解不足以使这种关联正确发生,或者没有足够的相关文档,或者 ORM 不是为此用途而设计的(或这些用途的任何组合),但我需要它按照我的要求工作和现在可以了。如果它以任何方式冒犯我,我深表歉意。批评和建议总是受欢迎的。

def create(self, cr, uid, vals, context=None):
    """Creates a new dbe.document instance. Called by both internal app and client.
       documents are associated to dbe.vendor, dbe.application and dbe.certification.
    @param vals: All dbe.document field values as a dictionary.
    @return ID of new dbe.document instance.
    """
    if context is None:
        context={}

    doc_id = None
    association_id = None
    # vendor_id is passed with vals when documents are created from the client side. 
    new_vendor_id = vals.get('vendor_id',False)
    if new_vendor_id:
        doc_id = super(dbe_document,self).create(cr, uid, vals, context=context)
        _logger.debug("<CREATE> DBE Document (%d) created for vendor #%d by user %d", doc_id, new_vendor_id, uid)
    else: # within OpenERP we cannot get vendor_id from context so we do it caveman style.
        doc_id = super(dbe_document,self).create(cr, uid, vals, context=context)
        association_id = self.read(cr, uid, doc_id, ['application_id', 'certification_id'], context=context)
        if association_id['application_id']:
            application_id = association_id['application_id']
            application_obj = self.pool.get('dbe.application')
            application = application_obj.browse(cr, uid, application_id)
            new_vendor_id = application.vendor_id.id
        elif association_id['certification_id']: # since there is no application maybe its a certification related doc....
            certification_id = association_id['certification_id'][0]
            certification_obj = self.pool.get('dbe.certification')
            certification = certification_obj.browse(cr, uid, certification_id)
            new_vendor_id = certification.vendor_id.id
        else:
            raise osv.except_osv(_('ValidateError'), _('<CREATE> A DBE Document cannot be created without an application or certification - Association Missing!'))

        if new_vendor_id: # brute-force association to dbe.vendor.
            vals.update({'vendor_id': new_vendor_id})
            self.write(cr, uid, doc_id, vals, context)
            _logger.debug("<CREATE> DBE Document (%d) created for vendor #%d by user %d", doc_id, new_vendor_id, uid)
        else: # too bad - no vendor, no doc.
            _logger.debug("<CREATE> DBE Document (%d) removed because vendor_id missing for user %d", doc_id, uid)
            raise osv.except_osv(_('ValidateError'), _('<CREATE> A DBE Document cannot be created without selecting a Vendor - Vendor Id Missing!'))

    return doc_id
于 2013-08-14T17:41:58.443 回答
0

最好使用 fields.related 进行这样的关联,您可以在其中以“C”的形式从“B”引用“A”。

于 2013-08-19T10:30:57.703 回答