Odoo15中让Many2one字段下拉保持传入ID顺序的方法
Odoo15 保持Many2one下拉选项按指定ID顺序显示的实现方案
核心思路
Odoo默认会按关联模型(如sale.order)的_order字段排序下拉选项,要强制按传入的ID列表顺序显示,需通过后端控制搜索结果的排序逻辑——利用上下文传递目标ID列表,并重写关联模型的name_search方法实现自定义排序。
具体实现步骤
1. 在自定义模型中传递目标ID上下文
在触发onchange的方法中,设置Many2one字段的domain过滤规则,同时将目标ID列表传入系统上下文:
from odoo import models, fields, api class CustomModel(models.Model): _name = 'custom.model' _description = '自定义模型' many2one_sale_order = fields.Many2one('sale.order', string='销售订单') custom_field_char = fields.Char(string='自定义字段') @api.onchange('custom_field_char') def onchange_custom_field(self): # 示例目标ID列表,实际可根据业务逻辑动态生成 target_sale_ids = [1072, 1102, 1099] # 设置domain过滤出指定订单 self.domain = { 'many2one_sale_order': [('id', 'in', target_sale_ids)] } # 将目标ID列表传入上下文,供排序逻辑调用 self.env.context = dict(self.env.context, target_sale_ids=target_sale_ids) # 清空当前选中值,避免残留不符合新选项的记录 self.many2one_sale_order = False
2. 重写sale.order的name_search方法
通过继承sale.order模型,重写name_search方法,判断上下文是否存在目标ID列表,若存在则按该列表顺序返回搜索结果:
class SaleOrder(models.Model): _inherit = 'sale.order' @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): # 检查上下文是否携带目标ID排序规则 target_ids = self.env.context.get('target_sale_ids') if target_ids: # 严格按目标ID列表的顺序读取记录 ordered_records = self.browse(target_ids) # 返回Odoo要求的(ID, 显示名称)格式列表 return [(rec.id, rec.display_name) for rec in ordered_records] # 无特殊排序需求时,执行原有搜索逻辑 return super().name_search(name=name, args=args, operator=operator, limit=limit)
注意事项
- 若目标ID列表是动态生成的,需确保
onchange方法中始终传递最新的ID列表到上下文。 - 重写
name_search时仅在上下文存在target_sale_ids时触发自定义排序,避免影响其他场景下的sale.order搜索逻辑。 - 上线前需清空浏览器缓存,确保新的上下文逻辑生效。
内容的提问来源于stack exchange,提问作者Sidharth Panda
相关产品推荐
相关产品推荐

