Enable Dark Mode!
By: Sonu S

How to Create a Custom Field Type in Odoo 17

Technical Odoo 17

Odoo 17 is a comprehensive suite of business applications that has been redesigned to be faster, more secure, and packed with exciting AI solutions. It includes a wide array of seamlessly integrated applications, making it a game-changer for businesses looking to streamline their operations and foster growth. As a framework, Odoo is known for its many customizable fields and templates. However, sometimes manufacturers have to use new equipment due to complex business models or purely operational reasons. In both cases, the developer needs to define the new type, which can be the old type of the existing field or just the new type. We can define fields for all data types that Postgresql allows. But, we need to analyze how the field works in different situations. For example, if you define a new field to store time values, you must define how Odoo views, cache, and export options will read that field.
In this blog, we will talk about creating point data that represents the details of the map.
We will use the data generated by Postgres dot which should look like this (x,y). To achieve this goal, please follow the steps below.
First, we need to create a new Python file to define the fields. Instead of the current working file, create a separate file so it can be referenced anywhere.
from odoo.fields import Field
class Point(Field):
    """ Encapsulates an :class:`point`. It inherits the odoo.fields."""
    """Field class in order to get all the basic features of an odoo field"""
    type = 'point'
    """ The postgresql data type we're using for this field"""
    column_type = ('point', 'point')
    def convert_to_column(self, value, record, values=None, validate=True):
        # Converting to column inorder to save the data
        # Since we're using builtin postgres type
        # no need for extra efforts
        return value
    def convert_to_record(self, value, record):
        # Converting to colurecord inorder to handle the data
        return value or {}
    def convert_to_read(self, value, record, use_name_get=True):
        # Converts the data to a readable format
        # Just on case if we have any size incompatibility
        # here, it's fine
        return value
    def convert_to_export(self, value, record):
        # Converting the data to be Excel or csv compatible
        if value or value == "":
            return value
        return ''
Since we are defining a new field type we need to import it where we need to use it, it will not be in the built in odoo.fields and we will need to import it separately. See the code below for model.py to see how to use it in your model.
from odoo import models, fields
from .custom_fields import Point
class ResPartner(models.Model):
   _inherit = 'product.template'
   point = Point(string="Point on Map")
let’s create a new QWeb template for your custom widget. This template will be used to display the X and Y values of the Point field in the view. Here’s how you can do it:
Create a new file named point_field.xml under static/src/xml:
<?xml version="1.0" encoding="UTF-8" ?>
<templates id="template" xml:space="preserve">
    <t t-name="FieldPointWidget">
        <div t-attf-class="o_field_point {{ props.value ? 'o_has_value' : '' }}">
            <t t-if="props.value">
                <span t-esc="props.value.x"/> , <span t-esc="props.value.y"/>
Define the JavaScript for the Widget. Create a file called point_widget.js under static/src/js:
odoo.define('my_module.point_widget', function (require) {
    "use strict";
    const { Component, hooks } = owl;
    const { useState } = hooks;
    const fieldRegistry = require('web.field_registry');
    class PointWidget extends Component {
        constructor() {
            this.state = useState({ value: this.props.value });
    PointWidget.template = 'FieldPointWidget';
    fieldRegistry.add('point_widget', PointWidget);
    return PointWidget;
Then all are done, we use this point_widget in the XML view that we needed,
<?xml version="1.0" encoding="utf-8"?>
   <record id="product_form_inherit_add_point_view" model="ir.ui.view">
   <field name="name">product.template.form.point</name>
   <field name="model">product.template</field>
   <field name="inherit_id" ref="sale.product_template_form">
       <field name="categ_id" position="after">
           <field name="point" widget="point_widget"/>
The process of creating a custom field type in Odoo 17 is a testament to the platform’s flexibility and adaptability. This feature allows for the tailoring of the system to meet unique business requirements, enhancing its utility as an enterprise resource planning software. However, it necessitates a solid grasp of both the Odoo framework and Python programming. In conclusion, the creation of custom field types, while potentially challenging, underscores the robust and versatile nature of Odoo, enabling the customization of business processes for improved efficiency. It’s a powerful tool that, when utilized effectively, can significantly enhance business operations.
To read more about creating & managing a custom field from a function in Odoo 17, refer to our blog How to Create & Manage a Custom Field From a Function in Odoo 17

If you need any assistance in odoo, we are online, please chat with us.


Leave a comment




Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635



Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.



Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message