Search Here

Inheritance in Models and Views (Form or Tree)

In Odoo/OpenERP we can inherit or use existing modules object/class/model and views. We can also inherit single field of existing modules. The question is why we need such inheritance.

The purpose of inheritance or why we need inheritance is given below:
  1. To change attributes of some fields which exists on existing/custom model (e.g. making fields readonly,invisible)
  2. To add/modify/delete old or new fields in existing/custom model (e.g. Product, Sales, HR, Fleet Management, Attendance modules model etc)
  3. We can also add buttons in already existing/custom model (form and tree) view by using inheritance
Before going directly into coding I want to tell you about inheritance.

What is Inheritance in Odoo

Inheritance means we are going to use or inherit old class/model, properties, methods and views in new class/model. This concept is related to Object Oriented Programming. In Odoo/ERP we extend properties, fields and views of an existing model in a modular way.

Inheritance in Models and Views

Inherit existing model or class in Odoo

To inherit custom or existing models we use _inherit keyword.
Models.py
 
class groups(models.Model):
_inherit = 'res.groups'
# we inherited res.groups model which is Odoo/OpenERP built in model and created two fields in that model.
field_1 = fields.Char(required=True,string="Field One")
field_2 = fields.Boolean(default=False,string="Field Two")

Code Description

In above code snippet we have inherited res.groups model of Odoo, after inheritance we declare two fields the first one is of type Char and the second is Boolean type. This means that we are adding two fields in already create (res.groups) model/class by using inheritance. Now these two fields are also available in inherited model/class. Here we are define Char and Boolean type field you can define or add each type of field such as (Char, Integer, Float, Boolean, Many2many, Many2one, One2many, Date etc).

Now that we have inherited model/class of an existing model. Now we are going to inherit views.

Inherit existing views (form or tree) in Odoo

To inherit views (form and tree) of an existing model or class follow below steps.
  1. Create a new XML file in your_module >> views >> inherited_form_view.xml or inherited_tree_view.xml
  2. Use below code to inherit form and tree view
<openerp>
<data>
<record model="ir.ui.view" id="res_group_form_view_inherited">
<field name="name">res.group.form.view.inherited</field>
<field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_form" />
<!-- <field name="groups_id" eval="[(6, 0, [ref('your_module.group_xml_id')])]"/> -->
<field name="priority" eval="15"/>
<field name="arch" type="xml">

<xpath expr="//field[@name='name']" position="after"> <field name="field_1"/> </xpath> <xpath expr="//field[@name='user_name']" position="after"> <field name="field_2"/> </xpath> </field> </record> </data>
</openerp>

Code Description

In above code we have inherited res.groups form view. Here the main line is given below, its mean that we are going to inherit view_groups_form which is located in base module. Actually we are referencing here the parent or original form id of res.groups model named view_groups_form.

<field name="inherit_id" ref="base.view_groups_form" />

Now that we have inherited parent form of res.groups model. Now we have to display fields that we have created in that model named field_1 and field_2. To display that fields we have used xpath expression. In "expr" attribute we used "//field[@name='name']" and "position="after"", its mean that place our newly created field after name field of parent form view. Position attribute have following values.

  1. position="after" : To display field after parent form view field mentioned in "expr"
  2. position="before" : To display field before parent form view field mentioned in "expr"
  3. position="inside" : To display field inside notebook of parent form view
  4. position="attributes" : To change field attribute such as read only and visibility of a field
  5. position="replace" : To replace parent form view field with your newly created field
In "expr" attribute you may use following values.

1- expr="//div[@name='buttons']"

2- expr="//group[@name='parent']" 3- expr="." 4- expr="//field[@name='target_move']" 5- expr="//notebook/page[@string='Filters']" 6- expr="//page[@name='filters']" 7- expr="/form/notebook/page/field[@name='line_id']/tree/field[@name='analytic_account_id']" 8- expr="/form/notebook/page/field[@name='line_id'] 9- expr="//page[@name='statement_line_ids']/field[@name='line_ids']/tree/field[@name='amount']" 10- expr="//button[@name='invoice_cancel']" 11- expr="//label[@for='module_account_followup']"
12- expr="/tree/field[@name='user_id']"

Similarly if you want to display fields/tabs/pages,notebook etc in inherited form view use below code snippet.

Display field_1 after name field using inheritance
<xpath expr="//field[@name='name']" position="after">
<field name="field_1"/>
</xpath>

Make existing field required using inheritance
<field name="template_id" position="attributes">
<attribute name="attrs">{'required': 1}</attribute>
</field>

Replace existing field and display a new inherited field
<field name="field_id_which_you_want_to_replace" position="replace">
<field name="field_id_which_you_want_to_display"/>
</field>

Inherit existing notebook and page and display new field inside it
<notebook position="inside">
<page string="Overdue Payments" position="inside">
<separator string="Overdue Payments Message"/>
<field name="overdue_msg"/>
</page>
</notebook>

Similarly you can inherit tree view.

<record id="res_group_tree_view_inherited" model="ir.ui.view">
<field name="name">res.group.tree.view.inherited</field>
<field name="model">res.groups</field>
<field name="inherit_id" ref="hr.view_groups_tree"></field>
<field name="arch" type="xml">

<xpath expr="//field[@name='job_id']" position="after"> <field name="employee_contracts"></field> <field name="state"></field> </xpath> </field>
</record>


Post a Comment

16 Comments

  1. Hi I do these instructions but I get the following error

    Field 'field_1' dosn't exist

    Could you help me please

    ReplyDelete
    Replies
    1. Dear here "field_1" could be any of your field, which you have to override

      Delete
  2. I have a question regarding view inheritance. I inherited a existing view and I want that view to use a new model. The new model is inherited from the model that is being used in that existing view. I keep getting error "widget is not a constructor" while performing this.

    ReplyDelete
  3. i am getting the error that field doesnt exist.This happens only when i am trying to put a new field in the tree. Same field is working in the form but that field is not working in the tree view.. Please help

    ReplyDelete
  4. I still don't understand about the expr syntax. When I tried to inherit a view and track a field to add another field after it I tried this expr:

    And it raised an error in upgrading the module. When my senior at work repair the code by changing it to:

    It worked. As I understand my code was similar to your 5th example above: expr="//notebook/page[@string='Filters']"
    Can you explain more for me in the path when to use double slash (//) when to use single slash (/)?

    ReplyDelete
  5. so i did this, in a custom module i created which inherited res.partner (model and view)






    and while, Odoo (12) throws no error, the fields did not show up in the Partner form view

    ReplyDelete
  6. It's very helpful to me, thank you and also google who bring me here

    ReplyDelete
  7. Hi, I want to inherit ODOO's default model lets say stock.picking model for my own two different models. in other words, I want to inherit a single odoo model in two different models(classes) that I have created. is it possible to inherit a single odoo model for more than one self defined classes? so that these two classes can behave differently. waiting for your response.
    Thank You

    ReplyDelete
  8. Hi,I have a question about position attribute "replace"
    I created a new record and inherited from other parent record so my code below:
    (parent field)


    and when i run program, was changed to from child record and was changed to too from parent record. I still think when i use inheritance for my new record and i custom in this record then from parent record must not changed???

    ReplyDelete
  9. Hi ,I created a lot of fields in model.py for inherit but i haven't got any model in database after inherit from openeducat admission, I depend app from Technical Name and inherit from exiting models but after restart and update there is no models in database.Please Help me .. Thank you.. Models and Openerp.py are below..
    MODEL.PY
    from openerp import models, fields

    class st_admission(models.Model):
    _inherit = 'op.admission.register'

    sex = fields.Selection([('male','Male'),('female','Female')], 'Sex', required=True),
    current_age = fields.Integer('Current Age'),
    prf_name = fields.Char('Preferred Name'),
    birthday = fields.Date('Date of Birth'),
    anti_enroll_date = fields.Date('Anticipated Enrollment Date'),
    last_grade = fields.Char('Last Grade Completed'),
    anti_grade_enter = fields.Char('Anticipated Grade To Enter'),
    passort = fields.Char('Passort #', help='If a child has dual citizenship, provide additional passport information'),
    country = fields.Char('Country for Passport'),
    exp_date = fields.Date('Expiration Date for Passport'),
    nrc_no = fields.Char('NRC'),
    type_visa = fields.Selection([('debit','Debit Card'),('credit','Credit Card')], 'Type of Visa Held', required=True),
    religion = fields.Char('Religion'),
    nationally = fields.Char('Nationally'),
    is_myanmar = fields.Selection([('yes','YES'),('no','NO')], 'Myanmar_citizen?'),
    home_language = fields.Char('Home Language'),
    oth_language = fields.Char('Other Language'),
    current_address = fields.Text('Current Residence Address'),
    home_phone = fields.Integer('Home Phone', required=True),
    home_fax = fields.Integer('Home Fax'),
    email = fields.Char('Email', required=True),
    emergency_phone = fields.Integer('Emergency Contant Phone', required=True),

    __openerp__.py files
    {
    'name': 'Advance for addmissions',
    'version': '1.0',
    'description': 'Add more information for Addmissions.',
    'author': 'Hannay Oo',
    'depends': ['openeducat_admission'],
    'data': [
    #'views/admission.xml',
    ],
    'application': True,
    'installable': True,
    }

    ReplyDelete
  10. how to inherit from inherited view?

    ReplyDelete
  11. This doesnot work in odoo 13 community showing no object found. Pls advise

    ReplyDelete