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

原论坛用户的基本信息和发帖这里都予以保留,请注意:原论坛用户无需重新注册新用户,但是您的密码需要重置

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

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

运用插入 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]]



  • 这是我要用到的模块
    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 result

    def _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参数的格式为:[code]store={‘object_name’: (function_name,[‘field_name1’,’field_name2’],priority)}[/code]是当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, osv

    Dimensions 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 res

    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 result

    def _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

    def _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 True

    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_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]]



  • 有人理解我的问题吗......
    我也觉得我叙述得太难明白...


登录后回复
 

与 Odoo 中文社区 的连接断开,我们正在尝试重连,请耐心等待