运用插入 many2many 属性的字段
-
这是我要用到的模块
sale_product_multistep_configurator.zip
product_variant_multi.zip
product_variant_configurator.zip在addon/product_variant_multi/product_variant.py 的varants[code] _columns = {
'dimension_value_ids': fields.many2many('product.variant.dimension.value', 'product_product_dimension_rel', 'product_id','dimension_id', 'Dimensions', domain="[('product_tmpl_id','=',product_tmpl_id)]"),
'variants': fields.function(_variant_name_get, method=True, type='char', size=64, string='Variants', readonly=True,
store=
'product.variant.dimension.type': (_get_products_from_dimension, None, 10),
'product.product': (_get_products_from_product, None, 10),
}[/code]但是他是一个many2many的属性,使用XML-RPC就不知道如何插入这类型的属性。望各位能指点迷津。
谢谢大家。[[i] 本帖最后由 popkar77 于 2009-8-5 08:48 编辑 [/i]]
-
我看代码的时候不是太明白many2many field的store是怎么使用的。[code]
def _get_products_from_dimension(self, cr, uid, ids, context={}):
result = []
for type in self.pool.get('product.variant.dimension.type').browse(cr, uid, ids, context=context):
for product_id in type.product_tmpl_id.variant_ids:
result.append(product_id.id)
return resultdef _get_products_from_product(self, cr, uid, ids, context={}):
result = []
for product in self.pool.get('product.product').browse(cr, uid, ids, context=context):
for product_id in product.product_tmpl_id.variant_ids:
result.append(product_id.id)
return result
..............................
'variants': fields.function(_variant_name_get, method=True, type='char', size=64, string='Variants', readonly=True,
store=
'product.variant.dimension.type': (_get_products_from_dimension, None, 10),
'product.product': (_get_products_from_product, None, 10),[/code]
在product.product里面字段是这样
[attach]209[/attach]
但是我使用XML-RPC向variants插入字符串却没有反应,既没有报错,也没有插入成功[[i] 本帖最后由 popkar77 于 2009-8-6 09:35 编辑 [/i]]
-
确实看不太明白你的问题。
你为什么认为variant字段是many2many字段?
variant字段是一个函数字段(fields.function), 其返回的数据类型是'char'。[code]'variants': fields.function(_variant_name_get, method=True, type='char', size=64, string='Variants', readonly=True,
store= {
'product.variant.dimension.type': (_get_products_from_dimension, None, 10),
'product.product': (_get_products_from_product, None, 10),
}[/code]其中store参数的格式为:store={‘object_name’: (function_name,[‘field_name1’,’field_name2’],priority)}
是当object_name的field_name1, field_name2 ...发生变化时调用function_name,并将返回的值作为函数字段的对应函数(本例中即:_variant_name_get)的运行参数。
这个字段的值实际上是计算出来的,并不是你可以直接写进去的。
[[i] 本帖最后由 digitalsatori 于 2010-3-10 19:04 编辑 [/i]]
-
先谢谢版主回复...
啊...是我笔误写错了,是function fields字段。
现在我的想法是这样的通过其他的程序,读入一些product的variants名字,导入去openerp里面,所以想通过xml-rpc对里面的variants进行修改,您说variants是经过计算出来?也就是我直接插入是没有效果的?
我所讲得的many2many关系是[code]
'dimension_value_ids': fields.many2many('product.variant.dimension.value', 'product_product_dimension_rel', 'product_id','dimension_id', 'Dimensions', domain="[('product_tmpl_id','=',product_tmpl_id)]"),
[/code]它使用到了一个关联表,而我不知道应该使用XML-RPC对这个关联表进行插入。
完整代码:[code]from osv import fields, osvDimensions Definition
class product_variant_dimension_type(osv.osv):
_name = "product.variant.dimension.type"
_description = "Dimension Type"_columns = {
'name' : fields.char('Dimension', size=64),
'sequence' : fields.integer('Sequence', help="The product 'variants' code will use this to order the dimension values"),
'value_ids' : fields.one2many('product.variant.dimension.value', 'dimension_id', 'Dimension Values'),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete='cascade'),
'allow_custom_value': fields.boolean('Allow Custom Value', help="If true, custom values can be entered in the product configurator"),
}_order = "sequence, name"
def name_search(self, cr, user, name='', args=None, operator='ilike', context=None, limit=None):
if context.get('product_tmpl_id', False):
return super(product_variant_dimension_type, self).name_search(cr, user, '', args, 'ilike', None, None)
else:
return super(product_variant_dimension_type, self).name_search(cr, user, '', None, 'ilike', None, None)product_variant_dimension_type()
class product_variant_dimension_value(osv.osv):
_name = "product.variant.dimension.value"
_description = "Dimension Value"def _get_dimension_values(self, cr, uid, ids, context={}):
result = []
for type in self.pool.get('product.variant.dimension.type').browse(cr, uid, ids, context=context):
for value in type.value_ids:
result.append(value.id)
return result_columns = {
'name' : fields.char('Dimension Value', size=64, required=True),
'sequence' : fields.integer('Sequence'),
'price_extra' : fields.float('Price Extra', size=64),
'price_margin' : fields.float('Price Margin', size=64), #TODO: this field is not implemented yet
'dimension_id' : fields.many2one('product.variant.dimension.type', 'Dimension Type', required=True, ondelete='cascade'),
'product_tmpl_id': fields.related('dimension_id', 'product_tmpl_id', type="many2one", relation="product.template", string="roduct Template", store=True),
'dimension_sequence': fields.related('dimension_id', 'sequence', string="Related Dimension Sequence",#used for ordering purposes in the "variants"
store={
'product.variant.dimension.type': (_get_dimension_values, None, 10),
}),
}
_order = "dimension_sequence, sequence, name"product_variant_dimension_value()
class product_template(osv.osv):
_inherit = "product.template"_columns = {
'dimension_type_ids':fields.one2many('product.variant.dimension.type', 'product_tmpl_id', 'Dimension Types'),
'variant_ids':fields.one2many('product.product', 'product_tmpl_id', 'Variants'),
}def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default.update({'variant_ids':False,})
return super(product_template, self).copy(cr, uid, id, default, context)def button_generate_variants(self, cr, uid, ids, context={}):
def cartesian_product(args):
if len(args) == 1: return [(x,) for x in args[0]]
return [(i,) + j for j in cartesian_product(args[1:]) for i in args[0]]variants_obj = self.pool.get('product.product')
temp_type_list=[]
temp_val_list=[]for product_temp in self.browse(cr, uid, ids, context):
for temp_type in product_temp.dimension_type_ids:
temp_type_list.append(temp_type.id)
temp_val_list.append([temp_type_value.id for temp_type_value in temp_type.value_ids])if last dimension_type has no dimension_value, we ignore it
if not temp_val_list[-1]:
temp_val_list.pop()
temp_type_list.pop()if temp_val_list:
list_of_variants = cartesian_product(temp_val_list)for variant in list_of_variants:
constraints_list=[('dimension_value_ids', 'in', ) for i in variant]prod_var=variants_obj.search(cr, uid, constraints_list)
if not prod_var:
vals={}
vals['product_tmpl_id']=product_temp.id
vals['dimension_value_ids']=[(6,0,variant)]var_id=variants_obj.create(cr, uid, vals, {})
return True
product_template()
class product_product(osv.osv):
_inherit = "product.product"def _variant_name_get(self, cr, uid, ids, name, arg, context={}):
res = {}
for product in self.browse(cr, uid, ids, context):
r = map(lambda dim: (dim.dimension_id.name or '')+':'+(dim.name or '-'), product.dimension_value_ids)
res[product.id] = ' - '.join(r)
return resdef _get_products_from_dimension(self, cr, uid, ids, context={}):
result = []
for type in self.pool.get('product.variant.dimension.type').browse(cr, uid, ids, context=context):
for product_id in type.product_tmpl_id.variant_ids:
result.append(product_id.id)
return resultdef _get_products_from_product(self, cr, uid, ids, context={}):
result = []
for product in self.pool.get('product.product').browse(cr, uid, ids, context=context):
for product_id in product.product_tmpl_id.variant_ids:
result.append(product_id.id)
return resultdef _check_dimension_values(self, cr, uid, ids): # TODO: check that all dimension_types of the product_template have a corresponding dimension_value ??
for p in self.browse(cr, uid, ids, {}):
buffer = []
for value in p.dimension_value_ids:
buffer.append(value.dimension_id)
unique_set = set(buffer)
if len(unique_set) != len(buffer):
return False
return Truedef copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default.update({'variant_ids':False,})
return super(product_product, self).copy(cr, uid, id, default, context)_columns = {
'dimension_value_ids': fields.many2many('product.variant.dimension.value', 'product_product_dimension_rel', 'product_id','dimension_id', 'Dimensions', domain="[('product_tmpl_id','=',product_tmpl_id)]"),
'variants': fields.function(_variant_name_get, method=True, type='char', size=64, string='Variants', readonly=True,
store=
'product.variant.dimension.type': (_get_products_from_dimension, None, 10),
'product.product': (_get_products_from_product, None, 10),
}),
}
_constraints = [ (_check_dimension_values, 'Several dimension values for the same dimension type', ['dimension_value_ids']),]product_product()[/code]下面是图
[attach]210[/attach]版主所的说的计算应该就是,把下面选择好的dimension Value 存到Variants上面,我现在问题就是:
1.如何插入一个many2many的属性,也就是如何使用XML-RPC插入他们直接的关联表'product_product_dimension_rel‘。
2.如果插入后,那个计算variants的方法会不会自动执行,因为根本目的我也是要改变variants的值。
3.store那里的返回值我看到的是product.id。在_variant_name_get函数里面作为参数,是这里吗?[code]
res[product.id] = ' - '.join(r)
[/code][[i] 本帖最后由 popkar77 于 2009-8-6 16:02 编辑 [/i]]