将孩子与父母的父母联系起来?

时间:2013-08-13 14:19:28

标签: associations openerp

在OpenERP中,我有3个模型,A,B和C.如果你从A的表单开始,有一个孩子B的树列表。当你点击其中一个孩子时,表格中有一个树列表孩子C.我需要C孩子与父母A和B相关联,但他们只会将自己与B联系起来,尽管A和B都有很多2个字段。我怎么能强迫这种关联呢? 我已经使用active_id和default_get查看了解决方案但没有成功。上下文对象似乎对此有用,但我看不到用两个父对象的id动态设置它,因为我从A向下钻取到导航表单。我不明白为什么上下文通常不会像在各种Web框架中那样以这种方式保存上下文。

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

我是否应该在C的create方法中使用subselect查询执行简单更新以实现此目的,还是会破坏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,因为它是必填字段,但它是我想自动填充的字段。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

最好使用fields.related进行这种关联,你可以用“C”形式从“B”中引用“A”。