Odoo中文社区可以通过以下两个域名访问:shine-it.net , odoo.net.cn

由于系统升迁的原因,本论坛部分较早期的内容存在格式和链接损坏失效的问题,并非本论坛系统本身的缺陷,望谅解

本社区没有维护任何QQ群讨论组,任何与本社区同名的QQ群讨论组的言论与本社区无关!

开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

如果您登录系统碰到问题,请在微信公众号留言:

如何控制many2one多对一的字段下拉框显示自己所想要的数据问题



  • 问题点:
    在实际的开发过程中,有碰到这样的一个问题
    customer and supplier and user 都是在res.partner表中
    产品也有一个product.supplierinfo 表用来装载该产品的供应商
    而我定义了一个字段
            'name' : fields.many2one('res.partner', 'supplier',                      domain=[('supplier','=',True)],
                                    ondelete='cascade',required=True,  help="Supplier of this product"), 
    想显示 product.supplierinfo 中的供应商

    解决办法:
    1.我想通过domain来完成,于是使用了 domain=[('supplier','in',func)]
      但是测试时一直没通过
     经jeff 与步科,ccods,海飞等众多大神们,佛祖们指导,最终得出的解决办法是,该写法不符合规范,
     正确写法应该为:domain=my_domain()

      然后再定义一个函数
      def my_domain()
      return "[('id','in',["+','.join(map(str,ids))+"])]"  #假如ids=[1,2,3]
      该函数的作用是返回一个字符串
     则回到原字段定义中为:
            'name' : fields.many2one('res.partner', 'supplier', domain=[color=limegreen]"[('supplier','in',[1,2,3])]"[/color],
                                    ondelete='cascade',required=True,  help="Supplier of this product"),
      对此我进行了domain="[]" 与 domain=[] 测试
     发现只有 domain=[
    ] 才起作用,对此疑问我向jeff咨询中得出答案:该两种都是一样的效果,
     海飞兄说,官方写法为:domain=[
    ] ,
     同时我自己测试了,并找了ccods与东莞-老马 进行帮忙测试这个“”问题,结果是,ccods的两种写法效果一样,东莞-老马的跟我的一样,只有domain=[
    ****] 才起作用
     
     对此疑问只能归为版本问题,进行保留处理
     
     2:因为my_domain()返回的是字符串,所以导致了虽然字段的domain=“可变值” 但却起不到作用
     对此我又进行进一步的测试
     海飞兄提示说:domain实际是一个list,所以不应该用字符串,应该用数组
     我也有跟踪仔细观察过,domain=[('supplier','in',[1,2,3])] 
      在此,进行一下数组及元组的解析,
     数组=[]
     元组=()
     于是我猜测,domian=[元组1,元组2,元组3] 这种写法
     于是我将my_domain()函数改成:
         def my_domain():
       ids=[1,2,3,4]    #为方便测试我直接给它设置了一个固定数组
            reval=[]
            reval=['id','in']
            reval.append(supplier_bom_ids)
           
            stuple=tuple(reval)
           
            returlist=[]
            returlist.append(stuple)
            #reval="domain=[('id','in',["+','.join(map(str,ids))+"])]"
            #reval="[('id','in',["+','.join(map(str,ids))+"])]"
            print conset_product_id
            print "以下是reval的值"
            print returlist 
            return returlist

      则返回的是一个带元组的数组,此时,测试成功,该my_domain()返回的结果  起作用了,
      于是我想将ids转成一个可变值,但此时就不成功了
      我再进行跟踪观察,发现_columns在初使化时就已经运行了,此时context或者全局参数根据还没能产生
     
      所以使用domain=my_domain() 方法宣告失败

    方法2:
      fields_view_get –> fields_get –> read
      该方法我测试过,但因为能力有限,这些函数的原理我也没搞得怎么明白,不敢发表评论,
      fields_view_get 在模块show之前,会进行加载
      fields_get 可以更改_columns里的值,但是即使更改后,也不见起作用,所以我估计在运行fields_get时,该many2one已经加载完数据了
      
     
    最终结果:问题还是没解决得,实在辜负了群里众位大神们的帮助



  • 没看懂。。。。
    是不是要在界面上只能选该产品已定义过的供应商啊。
    直接many2one product.supplierinfo不行么?



  • 最终答案测试出来了,
    1:fields_view_get 中判断相应的view_type=你想要控制的view,比如tree or form
        判断fields中是否含有你想要控制的字段,如我上面所说的name字段
        调用 fields_get 函数,更改该字段的domain值 
      注:被控制下拉的字段,在xml中的视图中,不能含有 widget="selection" 否则不生效
      我测试是这样的,具体是什么原因不知道,实在很抱歉
      
      我用的是该方法,并测试成功
    2:最简单的就是many2one加上related  (jeff 提示,我有做过,方法可行)
    3:用selection类型 再用method 填充  (jeff 提示,我没有测试过)

    在此,再次感谢jeff ,步科,ccods,海飞众人的帮助



  • 具体代码如下
        def fields_get(self,cr,uid,fields=None,context=None):
            res=super(bom_supplierinfo,self).fields_get(cr,uid,fields,context)
            global conset_product_id
            global supplier_bom_ids 
            if 'name' in res:
                res['name']['domain']=[('id','in',supplier_bom_ids)]     
            return res
        def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
            self.fields_get(cr,uid,'name',context=context)
            res = super(bom_supplierinfo,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
            if view_type!='form':
                return res
            if context is None:
                context = {}
            fields=res.get('fields',{})
            if fields:
                if fields.get('name'):
                    results=self.pool.get('res.partner').read(cr,uid,supplier_bom_ids,['name'],context)
                    print 'show the Name value'
                    for r in results:
                        print r['id']
                    #res['name']=results
                    self.fields_get(cr,uid,'name',context=context)
                    res['name']=results
                   
                    #res['fields']=self.fields_get(cr,uid,'name',context=context)
            return res 



  • 好强!!

    借问一下,supplier_bom_ids在哪里赋值的?



  • 我其实是想用context传值的,但水平有限,于是我在模块用使用了全局变量
    惭愧啊


Log in to reply