python-3.xxmlpostgresqlodooodoo-15

I have a problem inheriting from res.partner


I have a question regarding res.partner in Odoo 15.0 I hope you can help me.

I am creating a model Student and I want to inherit fields like name, phone and email from res partner in my new model. But I am having several troubles with it. I have seen several people inheriting from other modules with success, but just adding a field or something like that. But I am having all sorts of problems. I don't know what is the correct way do do it.

I tried inheriting it directly by doing this first:

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

I got this error:

TypeError: Many2many fields student.channel_ids and res.partner.channel_ids use the same table and columns

So I had to define student_channel_ids separately and add that to the Student model:

student_channel_ids = fields.Many2many( 'mail.channel', relation='student_mail_channel_rel', column1='student_id', column2='channel_id', string='Channels')

Then it showed me this message:

psycopg2.errors.DuplicateColumn: ya existe la columna «signup_token» en la relación «res_partner» (dunno why suddenly in Spanish)

Hinting that the column signup_toke already exists in the res_partner relation.

I gave up and tried using the res.partner thing directly like this:

partner_id = fields.Many2one('res.partner', string='Partner', required=True, ondelete="cascade")

This is how it ended:

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

This is the view:

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

But now I am having troubles with the views and I don't even know if I am importing the fields I need correctly. Help please, this thing is driving me nuts!


Solution

  • You could use the "delegation inheritance" instead. A good example is model res.users:

    class Users(models.Model):
        """ User class."""
        _name = "res.users"
        _description = 'Users'
        _inherits = {'res.partner': 'partner_id'}
    
        partner_id = fields.Many2one('res.partner', required=True, ondelete='restrict', auto_join=True, index=True,
            string='Related Partner', help='Partner-related data of the user')
    

    So your student class would look like this:

    class Student(models.Model):
        """ Student class."""
        _name = "student"
        _description = "Studends"
        _inherits = {'res.partner': 'partner_id'}
    
        partner_id = fields.Many2one('res.partner', required=True, ondelete='restrict', auto_join=True, index=True,
            string='Related Partner', help='Partner-related data of the student')
        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)