如何控制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已经加载完数据了
最终结果:问题还是没解决得,实在辜负了群里众位大神们的帮助 -
最终答案测试出来了,
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