Odoo15中多对多字段结合Sequence与Handle Widget的排序问题
Odoo15 多产品共享标签下的自定义排序实现方案
核心问题在于:共享标签的全局sequence字段无法满足单个产品的独立排序需求,必须将排序字段存储在产品与标签的多对多关联中间表中,以下是具体实现步骤:
1. 显式定义多对多关联中间模型
默认Odoo会自动生成多对多关联表,但无法添加自定义字段,因此需要手动创建中间模型,用于存储每个产品对应标签的独立排序值:
from odoo import models, fields class ProductTemplateTagRel(models.Model): _name = 'product.template.tag.rel' _description = '产品模板-标签关联表' _order = 'sequence asc' # 默认按排序值升序加载 product_template_id = fields.Many2one('product.template', required=True, ondelete='cascade') tag_id = fields.Many2one('product.tag', required=True, ondelete='cascade') sequence = fields.Integer(default=10, help="排序优先级,值越小展示越靠前") # 添加唯一约束,避免同一产品重复关联同一标签 _sql_constraints = [ ('unique_product_tag', 'unique(product_template_id, tag_id)', '同一标签不能重复关联到同一产品!'), ]
2. 修改产品模型的多对多字段定义
将原product.template中的tag_ids字段关联到自定义的中间模型,替换默认自动生成的关联表:
class ProductTemplate(models.Model): _inherit = 'product.template' tag_ids = fields.Many2many( 'product.tag', relation='product.template.tag.rel', # 对应中间模型的_name column1='product_template_id', column2='tag_id', string='产品标签' )
3. 调整视图配置,绑定中间表的排序字段
修改原视图配置,将拖拽对应的sequence字段替换为中间表的排序字段,同时开启视图可编辑以触发拖拽保存:
<field name="tag_ids"> <tree create="false" delete="false" editable="bottom"> <!-- 此处sequence为中间表的字段,而非标签模型的全局sequence --> <field name="sequence" widget="handle"/> <field name="name"/> <!-- 自动关联标签模型的name字段 --> </tree> </field>
4. 前端网站展示自动按自定义排序加载
由于中间模型已设置_order = 'sequence asc',直接调用产品的tag_ids字段即可获取按自定义顺序排列的标签列表,无需额外处理:
<!-- 网站QWeb模板示例 --> <div class="product-tags"> <t t-foreach="product.tag_ids" t-as="tag"> <span class="tag-item" t-esc="tag.name"/> </t> </div>
关键逻辑说明
- 中间表的
sequence字段为每个产品-标签关联对单独存储排序值,完全不影响标签的全局共享特性 - Odoo的
handle组件会自动处理拖拽后的排序值更新,无需额外编写后端逻辑 - 中间模型的
_order配置确保所有场景下读取标签时默认按自定义排序加载
内容的提问来源于stack exchange,提问作者Elhagag Abdalla
相关产品推荐
相关产品推荐

