Skip to content

Odoo Field Types: Complete Reference Guide

DeployMonkey Team · March 22, 2026 14 min read

Field Types Overview

TypePythonDatabaseUse For
Charfields.CharVARCHARShort text (name, code, email)
Textfields.TextTEXTLong text (description, notes)
Htmlfields.HtmlTEXTRich HTML content
Integerfields.IntegerINTEGERWhole numbers (quantity, count)
Floatfields.FloatNUMERICDecimal numbers (weight, rate)
Monetaryfields.MonetaryNUMERICCurrency amounts (price, total)
Booleanfields.BooleanBOOLEANTrue/false flags
Datefields.DateDATEDates without time
Datetimefields.DatetimeTIMESTAMPDates with time (UTC)
Selectionfields.SelectionVARCHARDropdown choices
Many2onefields.Many2oneINTEGER (FK)Link to one record
One2manyfields.One2manyVirtualReverse of Many2one
Many2manyfields.Many2manyRelation tableLink to many records
Binaryfields.BinaryBYTEA/fileFile uploads, images
Imagefields.ImageBYTEA/fileImages with auto-resize
Jsonfields.JsonJSONBStructured JSON data

Common Parameters

# Parameters available on ALL field types:
name = fields.Char(
    string='Display Name',     # Label shown in UI
    help='Tooltip text',       # Help text on hover
    required=True,             # Cannot be empty
    readonly=True,             # Cannot be edited
    index=True,                # Create database index
    default='value',           # Default value
    copy=True,                 # Copy when duplicating record
    groups='base.group_user',  # Only visible to this group
    tracking=True,             # Log changes in chatter
    store=True,                # Store in database (for computed)
    compute='_compute_name',   # Compute method
)

Char & Text

name = fields.Char(string='Name', required=True, size=128)
email = fields.Char(string='Email')
notes = fields.Text(string='Notes')
description = fields.Html(string='Description', sanitize=True)

# Char: single line, VARCHAR in DB, optional size limit
# Text: multi-line, TEXT in DB, no size limit
# Html: rich text with WYSIWYG editor, sanitized for XSS

Numbers

quantity = fields.Integer(string='Quantity', default=1)
weight = fields.Float(string='Weight (kg)', digits=(10, 3))  # 3 decimal places
price = fields.Monetary(string='Price', currency_field='currency_id')
currency_id = fields.Many2one('res.currency', default=lambda self: self.env.company.currency_id)

# Integer: whole numbers only
# Float: decimal, digits=(precision, scale)
# Monetary: like Float but with currency widget in UI

Date & Datetime

birth_date = fields.Date(string='Birth Date')
created_at = fields.Datetime(string='Created At', default=fields.Datetime.now)

# Date: stored as Python date object
# Datetime: stored in UTC, displayed in user's timezone

# Useful methods:
fields.Date.today()           # Today's date
fields.Datetime.now()         # Current datetime (UTC)
fields.Date.to_string(date)   # Convert to string
fields.Date.from_string(str)  # Convert from string

Selection

status = fields.Selection([
    ('draft', 'Draft'),
    ('confirmed', 'Confirmed'),
    ('done', 'Done'),
    ('cancelled', 'Cancelled'),
], string='Status', default='draft', required=True)

priority = fields.Selection([
    ('0', 'Normal'),
    ('1', 'Low'),
    ('2', 'High'),
    ('3', 'Urgent'),
], string='Priority', default='0')

# Stored as VARCHAR in DB (the first value in each tuple)
# Displayed as dropdown in UI

Relational Fields

# Many2one: link to ONE record of another model
partner_id = fields.Many2one(
    'res.partner',
    string='Customer',
    ondelete='restrict',  # restrict, cascade, set null
    domain=[('is_company', '=', True)],  # Filter options
)

# One2many: reverse of Many2one (virtual field)
order_line_ids = fields.One2many(
    'sale.order.line',    # Related model
    'order_id',           # Many2one field on related model
    string='Order Lines',
)

# Many2many: link to MANY records
tag_ids = fields.Many2many(
    'project.tags',       # Related model
    'project_task_tag_rel',  # Relation table name (optional)
    'task_id',            # Column for this model (optional)
    'tag_id',             # Column for related model (optional)
    string='Tags',
)

Binary & Image

# Binary: file upload
attachment = fields.Binary(string='File', attachment=True)
attachment_name = fields.Char(string='Filename')

# Image: auto-resizes to multiple sizes
avatar = fields.Image(string='Avatar', max_width=1920, max_height=1920)

# attachment=True: store in filestore (not database)
# attachment=False: store as base64 in database (not recommended for large files)

Json (Odoo 16+)

# Store structured data as JSONB
metadata = fields.Json(string='Metadata')

# Usage:
record.metadata = {'color': 'red', 'sizes': ['S', 'M', 'L']}
color = record.metadata.get('color')  # 'red'

Common Patterns

# Name + code pattern:
name = fields.Char(required=True)
code = fields.Char(required=True, index=True)

# Active flag (soft delete):
active = fields.Boolean(default=True)

# Sequence (ordering):
sequence = fields.Integer(default=10)

# Company field (multi-company):
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)

# User field (assignment):
user_id = fields.Many2one('res.users', string='Responsible', default=lambda self: self.env.user)

DeployMonkey

Claude Code generates Odoo models with correct field types from natural language descriptions. Describe your data model in plain English, and the AI creates the Python model with appropriate field types, parameters, and constraints.