Odoo 15.0 res.partner继承问题求助:Student模型字段与视图异常
Odoo 15.0 Student模型与res.partner关联问题解决方案
问题背景
开发Student模型时,希望复用res.partner中的name、phone、email等字段,过程中遭遇多轮异常,最终改用Many2one关联方式后,视图仍无法正常工作。
第一次尝试:直接继承res.partner
最初通过_inherit直接继承res.partner,代码如下:
from odoo import models, fields, api class Student(models.Model): _name = 'student' _inherit = 'res.partner' _description = 'Model to manage school students' registration_ids = fields.One2many('registration', 'student_id', string='Registration') student_DNI = fields.Integer(string='ID') course_id = fields.Many2one('course', string='Course') birth_date = fields.Date(string='Birth Date') age = fields.Integer(string='Age', compute='_compute_age', store=True) @api.depends('birth_date') def _compute_age(self): for student in self: if student.birth_date: today = fields.Date.today() student.age = today.year - student.birth_date.year else: student.age = 0
触发错误:
TypeError: Many2many fields student.channel_ids and res.partner.channel_ids use the same table and columns
第二次修改:自定义邮件频道字段
为解决字段冲突,在Student模型中重定义channel_ids:
student_channel_ids = fields.Many2many( 'mail.channel', relation='student_mail_channel_rel', column1='student_id', column2='channel_id', string='Channels' )
再次触发数据库错误(西班牙语提示):
psycopg2.errors.DuplicateColumn: ya existe la columna «signup_token» en la relación «res_partner»
(翻译:res_partner表中已存在signup_token列)
第三次调整:改用Many2one关联res.partner
放弃继承,改用Many2one字段关联res.partner,最终模型代码:
from odoo import models, fields, api class Student(models.Model): _name = 'student' _description = 'Model to manage school students' partner_id = fields.Many2one('res.partner', string='Partner', required=True, ondelete="cascade") registration_ids = fields.One2many('registration', 'student_id', string='Registration') student_DNI = fields.Integer(string='ID') course_id = fields.Many2one('course', string='Course') birth_date = fields.Date(string='Birth Date') age = fields.Integer(string='Age', compute='_compute_age', store=True) @api.depends('birth_date') def _compute_age(self): for student in self: if student.birth_date: today = fields.Date.today() student.age = today.year - student.birth_date.year else: student.age = 0
视图代码:
<odoo> <data> <record model="ir.ui.view" id="view_student_form"> <field name="name">student.form</field> <field name="model">student</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml"> <form> <xpath expr="//field[@name='email']" position="after"> <field name="birth_date"/> <field name="age"/> <field name="student_DNI"/> <field name="course_id"/> </xpath> </form> </field> </record> </data> </odoo>
此时视图无法正常渲染,且字段复用逻辑存疑。
解决方案
方案一:修复直接继承res.partner的问题
- 解决channel_ids冲突:
在Student模型中重定义channel_ids,指定独立关联表:channel_ids = fields.Many2many( 'mail.channel', 'student_mail_channel_rel', 'student_id', 'channel_id', string='Channels' ) - 解决signup_token重复问题:
- 测试环境可卸载模块后清理数据库残留字段
- 若需邮件功能,添加多继承确保字段逻辑正确:
_inherit = ['res.partner', 'mail.thread']
方案二:修复Many2one关联下的视图问题
当前视图错误在于继承了res.partner的视图,但模型为student,两者不匹配。可通过两种方式修复:
1. 创建独立Student视图
直接编写视图,通过widget嵌套显示res.partner字段:
<odoo> <data> <record model="ir.ui.view" id="view_student_form"> <field name="name">student.form</field> <field name="model">student</field> <field name="arch" type="xml"> <form> <sheet> <group> <!-- 嵌套显示res.partner字段 --> <field name="partner_id" string="Partner Details" widget="form" readonly="False"> <form> <field name="name"/> <field name="phone"/> <field name="email"/> </form> </field> <!-- Student自有字段 --> <field name="birth_date"/> <field name="age"/> <field name="student_DNI"/> <field name="course_id"/> </group> <notebook> <page string="Registrations"> <field name="registration_ids"/> </page> </notebook> </sheet> </form> </field> </record> <!-- 注册菜单与动作 --> <record model="ir.actions.act_window" id="action_student"> <field name="name">Students</field> <field name="res_model">student</field> <field name="view_mode">tree,form</field> </record> <menuitem name="Students" id="menu_student" parent="base.menu_partner" action="action_student"/> </data> </odoo>
2. 使用委托继承(推荐)
通过_inherits实现字段自动复用,同时避免继承冲突:
class Student(models.Model): _name = 'student' _inherits = {'res.partner': 'partner_id'} _description = 'Model to manage school students' partner_id = fields.Many2one('res.partner', string='Partner', required=True, ondelete="cascade") registration_ids = fields.One2many('registration', 'student_id', string='Registration') student_DNI = fields.Integer(string='ID') course_id = fields.Many2one('course', string='Course') birth_date = fields.Date(string='Birth Date') age = fields.Integer(string='Age', compute='_compute_age', store=True) # 重定义channel_ids避免冲突 channel_ids = fields.Many2many( 'mail.channel', 'student_mail_channel_rel', 'student_id', 'channel_id', string='Channels' ) @api.depends('birth_date') def _compute_age(self): for student in self: if student.birth_date: today = fields.Date.today() student.age = today.year - student.birth_date.year else: student.age = 0
此时视图可直接继承res.partner的表单视图:
<odoo> <data> <record model="ir.ui.view" id="view_student_form"> <field name="name">student.form</field> <field name="model">student</field> <field name="inherit_id" ref="base.view_partner_form"/> <field name="arch" type="xml"> <xpath expr="//field[@name='email']" position="after"> <field name="birth_date"/> <field name="age"/> <field name="student_DNI"/> <field name="course_id"/> </xpath> </field> </record> </data> </odoo>
内容的提问来源于stack exchange,提问作者Alex Aguirre
相关产品推荐
相关产品推荐

