如何在Odoo中通过按钮打开特定父记录关联子记录并过滤视图数据
Odoo中关联父记录打开子记录的解决方案(含业务场景示例)
嘿,我来帮你搞定这个问题!你提到的两个需求本质上是同一个逻辑:通过context传递父记录ID + domain过滤子记录,就能实现只显示特定父记录关联的子数据,完全适配你说的「选择课程/学位后,显示对应科目和修读学生」的业务场景。下面一步步给你讲清楚:
一、核心思路
核心就是两步:
- 从父记录(比如课程)的视图中,把当前记录的ID传递给子记录的操作/视图
- 在子记录的action或视图中,用
domain过滤出仅关联该父ID的记录
二、具体实现方式(两种方案可选)
方案1:通过Python方法实现(灵活度高,适合复杂场景)
假设你的模型结构是:
- 父模型:
course(课程/学位),字段name(名称) - 子模型:
subject(科目),字段course_id(关联课程的many2one字段) - 学生模型:
student,字段subject_ids(关联科目的many2many字段)
步骤1:在父模型视图中添加按钮
在课程的form视图里加一个按钮,点击后打开对应科目列表:
<!-- 课程form视图片段 --> <button name="action_open_related_subjects" string="查看对应科目" type="object" class="oe_highlight"/>
步骤2:在父模型中编写按钮触发的方法
在course模型的Python文件里,写一个返回action的方法,直接设置domain过滤:
class Course(models.Model): _name = 'course' _description = '课程/学位' name = fields.Char('名称', required=True) def action_open_related_subjects(self): # 确保当前只有一条父记录被选中 self.ensure_one() return { 'name': f"{self.name}的关联科目", 'type': 'ir.actions.act_window', 'res_model': 'subject', # 子模型的标识 'view_mode': 'tree,form', # 要打开的视图类型 'domain': [('course_id', '=', self.id)], # 关键:过滤出当前课程的科目 'context': {'default_course_id': self.id}, # 新增科目时自动关联当前课程 }
步骤3:拓展到显示修读学生
如果要从科目视图打开对应学生列表,同样的逻辑:
在科目form视图加按钮:
<button name="action_open_enrolled_students" string="查看修读学生" type="object"/>
在subject模型里写方法:
class Subject(models.Model): _name = 'subject' _description = '科目' name = fields.Char('科目名称', required=True) course_id = fields.Many2one('course', '所属课程', required=True) student_ids = fields.Many2many('student', string='修读学生') def action_open_enrolled_students(self): self.ensure_one() return { 'name': f"修读{self.name}的学生", 'type': 'ir.actions.act_window', 'res_model': 'student', 'view_mode': 'tree,form', 'domain': [('subject_ids', '=', self.id)], }
方案2:纯XML配置实现(无需写Python代码,适合简单场景)
如果你不想写Python方法,也可以直接通过XML配置action,利用context传递父ID:
步骤1:定义子记录的action
先创建一个科目列表的action,domain里通过context获取父ID:
<record id="action_subject_list_for_course" model="ir.actions.act_window"> <field name="name">课程关联科目</field> <field name="res_model">subject</field> <field name="view_mode">tree,form</field> <!-- 通过context获取父记录ID,过滤关联的科目 --> <field name="domain">[('course_id', '=', context.get('active_course_id'))]</field> </record>
步骤2:在父视图中添加按钮调用该action
在课程form视图里,按钮直接调用上面的action,并传递父ID到context:
<button name="%(your_module_name.action_subject_list_for_course)d" string="查看对应科目" type="action" context="{'active_course_id': active_id}"/>
三、关键知识点说明
domain的作用:直接限制视图显示的记录范围,这里通过父记录ID精准过滤,确保只显示关联数据context的作用:除了传递父ID给domain,还可以设置默认值(比如新增子记录时自动填充父关联字段)active_id:Odoo内置的context变量,代表当前打开的父记录ID,直接用就行
这样配置后,你点击课程视图的按钮,就能只看到该课程对应的科目;再点击科目里的按钮,就能看到修读该科目的学生,完全符合你的业务需求!
内容的提问来源于stack exchange,提问作者majid
相关产品推荐
相关产品推荐

