DEV Community

All Next Ver
All Next Ver

Posted on Edited on

How to Add Custom Fields to Odoo Contacts with a Small Custom Module

Almost every Odoo project ends up needing one extra field on the contact form: a customer segment, a preferred contact time, an internal reference. The clean way to add it is a small custom module that extends res.partner, not editing core files or using Studio exports.

In this post we build a module called partner_extra_fields that adds two fields to the contact form. It takes about ten minutes.

I wrote this for Odoo [VERSION YOU TESTED]. Field and view names below are standard, but check the notes at the end if you use a different version.

What we are building

A module that adds:

  • Customer Segment (a dropdown: Retail, Wholesale, Corporate)
  • Preferred Contact Time (free text)

Both appear on the contact form, right after the Tax ID field.

Step 1: Create the module structure

Inside your custom addons folder, create this:

partner_extra_fields/
├── __init__.py
├── __manifest__.py
├── models/
│   ├── __init__.py
│   └── res_partner.py
└── views/
    └── res_partner_views.xml
Enter fullscreen mode Exit fullscreen mode

Step 2: The manifest

__manifest__.py tells Odoo what your module is and which files to load.

{
    'name': 'Partner Extra Fields',
    'version': '1.0.0',
    'summary': 'Adds customer segment and preferred contact time to contacts',
    'category': 'Contacts',
    'depends': ['base'],
    'data': [
        'views/res_partner_views.xml',
    ],
    'license': 'LGPL-3',
    'installable': True,
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Extend the model

Odoo lets you extend an existing model with _inherit. We do not create a new table; we add columns to res.partner.

models/__init__.py:

from . import res_partner
Enter fullscreen mode Exit fullscreen mode

models/res_partner.py:

from odoo import fields, models


class ResPartner(models.Model):
    _inherit = 'res.partner'

    customer_segment = fields.Selection(
        [
            ('retail', 'Retail'),
            ('wholesale', 'Wholesale'),
            ('corporate', 'Corporate'),
        ],
        string='Customer Segment',
    )
    preferred_contact_time = fields.Char(string='Preferred Contact Time')
Enter fullscreen mode Exit fullscreen mode

And the root __init__.py:

from . import models
Enter fullscreen mode Exit fullscreen mode

Step 4: Show the fields in the form

Fields in the database are not visible until a view shows them. We inherit the standard partner form and place our fields after vat.

views/res_partner_views.xml:

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="view_partner_form_inherit_extra_fields" model="ir.ui.view">
        <field name="name">res.partner.form.inherit.extra.fields</field>
        <field name="model">res.partner</field>
        <field name="inherit_id" ref="base.view_partner_form"/>
        <field name="arch" type="xml">
            <field name="vat" position="after">
                <field name="customer_segment"/>
                <field name="preferred_contact_time"/>
            </field>
        </field>
    </record>
</odoo>
Enter fullscreen mode Exit fullscreen mode

Step 5: Install it

  1. Add your custom addons folder to addons_path in odoo.conf.
  2. Restart the Odoo service.
  3. Turn on developer mode, go to Apps, click Update Apps List.
  4. Search for "Partner Extra Fields" and click Install.

Open any contact. Your two fields should appear under Tax ID.

When you change the code later

Odoo does not reload Python or XML changes automatically. Restart the service and upgrade the module:

./odoo-bin -c odoo.conf -d your_database -u partner_extra_fields
Enter fullscreen mode Exit fullscreen mode

Common mistakes

  • Forgetting an __init__.py. If a folder has no __init__.py, Odoo ignores it silently.
  • Skipping the -u upgrade after changing a view, then wondering why nothing changed.
  • A wrong inherit_id. A typo in base.view_partner_form throws an error on install.
  • A missing anchor field. If the field you inherit after (vat) is not in your view, use an xpath against a field that is.
  • Version differences. Between Odoo versions, view tags and some attributes change (for example, list views were renamed from tree to list in newer versions). Always read the release notes for your version.

Wrapping up

That is the whole pattern: a model extension for the data, a view inheritance for the screen, and a manifest to tie them together. Once you are comfortable with it, you can add constraints, computed fields, security rules and reports the same way.

If you have a specific field you want to add, or an Odoo error you are stuck on, leave a comment and I will help where I can.

I work at All Next Ver, a software company in Dhaka building Odoo and custom ERP solutions.

Top comments (0)