Skip to content

Complete Field Types Guide

What Are Fields?

Technical Definition

Fields are the columns in your database table. Each field stores a specific type of data. Understanding field types helps you:

  • Know what kind of data can be stored
  • Understand why certain validations exist
  • Write better functional specifications

Basic Field Types

Field TypeWhat It StoresExample UseDatabase Storage
CharShort text (single line)Customer name, ReferenceVARCHAR (limited characters)
TextLong text (multiple lines)Description, Notes, AddressTEXT (unlimited)
HtmlFormatted text with stylingEmail templates, Product descriptionsTEXT with HTML tags
IntegerWhole numbers onlyQuantity, Age, CountINTEGER
FloatDecimal numbersWeight, DimensionsFLOAT/NUMERIC
MonetaryCurrency amountsPrice, Total amountNUMERIC (with currency link)
BooleanTrue/False (checkbox)Is Active, Is CompanyBOOLEAN
DateDate only (no time)Birth date, DeadlineDATE
DatetimeDate and timeOrder date, Last loginTIMESTAMP
SelectionPredefined choicesStatus, Type, PriorityVARCHAR (stores key)
BinaryFile attachmentsPDF, Excel, DocumentsBYTEA or file system
ImageImage filesProduct image, AvatarBYTEA (with auto-resize)
JsonStructured dataComplex configurationsJSONB
PropertiesDynamic sub-fieldsCustom fields per projectJSONB

Field Type Details with Examples

Char vs Text - When to Use Which?

Use Char ForUse Text For
Names (max ~255 chars)Descriptions (unlimited)
Reference numbersNotes and comments
Email addressesFull addresses
Phone numbersTerms and conditions

Key Difference

Char shows as a single-line input. Text shows as a multi-line textarea.

Selection Field - The Dropdown

Selection fields store a key internally but display a label to users.

Example: Order Status

What User SeesWhat's Stored in Database
Quotationdraft
Quotation Sentsent
Sales Ordersale
Cancelledcancel

Why This Matters

When filtering or searching via API/code, you must use the technical key (draft), not the label (Quotation).

Monetary Field - More Than Just a Number

A Monetary field is linked to a currency field. This allows:

  • Proper currency symbol display (EUR, USD, INR)
  • Correct decimal places (2 for EUR, 0 for JPY)
  • Currency conversion calculations

Example: Sale Order has amount_total (Monetary) linked to currency_id (Many2one to res.currency)

Properties Field - Dynamic Custom Fields

Properties Field

The Properties field allows creating custom sub-fields per record without database changes.

Use Case: Different projects need different custom fields:

  • Project "Website Redesign" needs fields: Browser compatibility, Responsive breakpoints
  • Project "ERP Implementation" needs fields: Go-live date, Training hours

With Properties, each project can have its own custom fields, and all tasks in that project inherit them!

Common Field Attributes

Every field in Odoo can have attributes that control its behavior. Understanding these is crucial for functional consultants.

AttributeWhat It DoesExampleFunctional Impact
stringLabel shown to usersstring="Customer Name"What appears on forms/lists
requiredMust have a valuerequired=TrueCan't save record without it
readonlyCan't be editedreadonly=TrueDisplay only, no editing
defaultPre-filled valuedefault="draft"New records start with this value
helpTooltip on hoverhelp="Enter name"Shows info icon with explanation
copyInclude when duplicatingcopy=FalseReference numbers shouldn't copy
indexCreate DB indexindex=TrueFaster searches on this field
trackingLog changes in chattertracking=TrueShows "Status: Draft → Confirmed"
groupsRestrict visibilitygroups="base.group_system"Only admins see this field

Required vs Default - Common Confusion

  • required=True: User MUST provide a value (even if there's a default)
  • default=value: Pre-fills the field, but user can leave it empty (unless also required)
  • Both together: Field is pre-filled AND mandatory

Example: Sale Order state has default='draft' and required=True - it always starts as draft and must have a state.

Field Sizes and Limits

Field TypeDefault LimitCan Customize?Notes
CharNo limit (was 256)Yes (size=N)Since Odoo 12, no default limit
TextUnlimitedNoUse for long content
Integer-2B to +2BNo32-bit signed integer
Float~15 digits precisionYes (digits)digits=(16, 2) = 16 total, 2 decimal
MonetaryCurrency-dependentAutoUses currency's decimal places
Binary~1GB (PostgreSQL)NoLarge files stored externally
ImageAuto-resizedYesmax_width, max_height attributes

Practical Examples by Business Scenario

Scenario: Product Catalog

Field NameTypeWhy This Type?
nameCharShort product name, single line
description_saleTextLong description for quotes
list_priceFloatPrice without currency formatting
standard_priceFloatCost price (company_dependent)
qty_availableFloatStock can be fractional (0.5 kg)
activeBooleanArchive/unarchive products
typeSelectionConsumable/Service/Storable
image_1920ImageProduct photo with auto-resize
barcodeCharEAN/UPC code, indexed for scanning

Scenario: HR Employee

Field NameTypeWhy This Type?
nameCharEmployee's full name
work_emailCharEmail with validation widget
birthdayDateOnly date needed, no time
genderSelectionmale/female/other choices
notesTextHR notes, can be lengthy
certificateSelectionEducation level dropdown
resume_line_idsOne2manyMultiple resume entries
image_1920ImageEmployee photo

Float Precision - The Decimal Problem

Why Float Precision Matters

Float fields can cause unexpected rounding issues. Consider this:

Unit Price: 10.00
Quantity: 3
Expected Total: 30.00
Actual (with float errors): 29.999999999997

Solution: Use the digits attribute to control precision:

  • digits=(16, 2) = 16 total digits, 2 after decimal (standard for prices)
  • digits='Product Price' = Uses named precision from settings
  • digits='Product Unit of Measure' = Higher precision for quantities

Named Decimal Precisions in Odoo

Precision NameDefault DigitsUsed For
Product Price2Prices, unit costs
Product Unit of Measure5Quantities (allows 0.00001)
Discount2Percentage discounts
Stock Weight2Product weights

Configuration

These can be configured in Settings → Technical → Database Structure → Decimal Accuracy

Date and Datetime - Timezone Handling

Critical: Timezone Behavior

Field TypeStorageDisplay
DateStored as-is (no timezone)Shows same date everywhere
DatetimeStored in UTCConverted to user's timezone

Example Problem: A meeting scheduled at "2024-01-15 10:00" in India (UTC+5:30) is stored as "2024-01-15 04:30" UTC. A user in New York (UTC-5) sees it as "2024-01-14 23:30"!

Solution: Use Date for deadlines/birthdays, Datetime for appointments/timestamps.

Selection Fields - Best Practices

Selection Field Structure

Selection fields have a list of (key, label) pairs:

python
state = fields.Selection([
    ('draft', 'Draft'),
    ('confirmed', 'Confirmed'),
    ('done', 'Done'),
    ('cancel', 'Cancelled'),
], default='draft')

Key Rules:

  • Keys: lowercase, no spaces, use underscores (stored in DB)
  • Labels: Human-readable, translatable (shown to users)
  • Keys can't be changed after data exists (would lose data!)
  • Labels can be changed anytime (just UI text)

Adding Options to Existing Selection Fields

You can extend selection fields using selection_add:

python
# Original field has: draft, confirmed, done
# Your module adds: on_hold

state = fields.Selection(
    selection_add=[('on_hold', 'On Hold')],
    ondelete={'on_hold': 'set default'}
)

ondelete Parameter

The ondelete tells Odoo what to do if the module is uninstalled - set records to default state.

Binary and Image Fields

Binary vs Image - When to Use Which

Use Binary ForUse Image For
PDF documentsProduct photos
Excel filesEmployee avatars
Any non-image fileCompany logos
Images that shouldn't be resizedAny image that needs thumbnails

Image Field Auto-Resize

Image fields automatically create multiple sizes:

  • image_1920 - Original/large (max 1920px)
  • image_1024 - Medium (max 1024px)
  • image_512 - Small (max 512px)
  • image_256 - Thumbnail (max 256px)
  • image_128 - Icon (max 128px)

Performance Tip

Always use the smallest size needed. Don't load image_1920 for a list view thumbnail!

Field Type Decision Matrix

Quick Reference: Which Field Type to Use?

I need to store...Use This TypeNot This
A name or titleCharText (overkill)
A description or notesTextChar (too limited)
A price with currencyMonetaryFloat (loses currency)
A percentageFloatInteger (no decimals)
A count or quantity (whole)IntegerFloat (unnecessary)
A quantity (can be partial)FloatInteger (can't do 0.5)
A yes/no choiceBooleanSelection (overkill)
A status with 3+ optionsSelectionChar (no validation)
A birthdayDateDatetime (has TZ issues)
An appointment timeDatetimeDate (loses time)
A document attachmentBinaryChar (can't store files)
A photo/logoImageBinary (no auto-resize)
Rich formatted textHtmlText (loses formatting)

Company-Dependent Fields

What Are Company-Dependent Fields?

In a multi-company environment, some fields need to store different values for each company. These are called company_dependent fields (formerly called "Property" fields).

How It Works

When a field has company_dependent=True:

  • The value is stored per-company in a JSONB column
  • Each user sees the value for their active company
  • Changing companies shows different values automatically

Common Company-Dependent Fields

ModelFieldWhy Company-Dependent?
product.templatestandard_priceDifferent cost in each warehouse/company
product.templateproperty_account_income_idDifferent income accounts per company
product.templateproperty_account_expense_idDifferent expense accounts per company
res.partnerproperty_account_receivable_idDifferent AR accounts per company
res.partnerproperty_account_payable_idDifferent AP accounts per company
stock.locationvaluation_in_account_idDifferent valuation accounts

Database Storage

Company-dependent fields are stored as JSONB with company IDs as keys:

json
{
  "1": 150.00,    // Company 1: Cost is 150
  "2": 175.50,   // Company 2: Cost is 175.50
  "3": 140.00     // Company 3: Cost is 140
}

For Functional Consultants

When exporting data or creating reports involving company-dependent fields:

  • The value shown depends on the user's active company
  • Direct SQL queries need to parse JSONB by company ID
  • Always verify which company's data you're viewing!

Common Mistakes with Field Types

Wrong Approach: Using Char for Prices

python
price = fields.Char()

Problem: Can't calculate, sort, or format properly. "100" comes before "20" alphabetically!

Correct:

python
price = fields.Monetary(currency_field='currency_id')

Benefit: Proper calculations, sorting, currency symbols.

Wrong Approach: Using Text for Emails

python
email = fields.Text()

Problem: Multi-line input, no email validation, wastes space.

Correct:

python
email = fields.Char()
# In view: widget="email"

Benefit: Single line, clickable mailto link, proper validation.

Wrong Approach: Datetime for Deadlines

python
deadline = fields.Datetime()

Problem: "Due Jan 15" might show as "Due Jan 14" in different timezones!

Correct:

python
deadline = fields.Date()

Benefit: "Due Jan 15" is Jan 15 everywhere in the world.

Wrong Approach: Float for Quantities Without Precision

python
qty = fields.Float()

Problem: May get rounding errors like 2.9999999 instead of 3.0

Correct:

python
qty = fields.Float(digits='Product Unit of Measure')

Benefit: Uses named precision (5 decimals) for consistent rounding.

Knowledge Check

Q1: Which field type for Product Price?

Answer: Monetary

Monetary fields handle currency formatting, rounding rules, and multi-currency calculations automatically. Float would lose precision and not show currency symbols.

Q2: Which field type for Deadlines?

Answer: Date

Date fields store only the date without time, so "Jan 15" is Jan 15 for everyone. Datetime would shift based on timezone.

Q3: What's the difference between Html and Text?

Answer: Html allows rich formatting and is sanitized; Text is plain text

Html fields provide a rich text editor and sanitize content to prevent XSS attacks. Text is for multi-line plain text like notes or descriptions.

Q4: What does tracking=True do on a field?

Answer: Logs changes in the chatter

When a tracked field changes, Odoo automatically posts a message in the chatter showing the old and new values, like "Status: Draft → Confirmed".

Q5: Why use digits='Product Price' instead of digits=(16, 2)?

Answer: Named precision is centrally configurable

Using a named precision allows administrators to change decimal places globally in Settings → Technical → Decimal Accuracy, affecting all fields using that precision.

Q6: What makes a field "company_dependent"?

Answer: It stores different values per company

Company-dependent fields (like standard_price on products) store values in JSONB format with company IDs as keys, allowing each company to have its own value.

Q7: When should you use Image instead of Binary?

Answer: When you need automatic resizing and thumbnails

Image fields automatically create multiple sizes (1920, 1024, 512, 256, 128 pixels). Use for photos, logos, avatars. Binary is for documents like PDFs.

Q8: Can you change a Selection field's key after data exists?

Answer: No - you would lose data

Selection keys are stored in the database. Changing a key would orphan existing records. You can only change labels (the display text) safely.