Skip to content

11. Field Properties

What Are Field Properties?

Properties are settings that control a field's behavior: Is it required? Can it be edited? What's the default value?

Why This Matters to You

Ever wondered why:

  • Some fields turn red and won't let you save without filling them? → required=True
  • Some fields are grayed out and can't be edited? → readonly=True
  • Some fields auto-fill when you create a new record? → default=...
  • Some changes appear in the chatter history? → tracking=True
  • Some fields are invisible to certain users? → groups="..."

These are all field properties in action. Understanding them helps you configure Odoo behavior and communicate requirements to developers.

Common Field Properties

PropertyTypeWhat It DoesExample Use
stringStringLabel shown to usersstring="Customer Name"
requiredBooleanMust be filled before savingrequired=True
readonlyBooleanCannot be edited by usersreadonly=True
defaultValue/FunctionInitial value for new recordsdefault=lambda self: fields.Date.today()
helpStringTooltip text on hoverhelp="Enter the full legal name"
indexBoolean/StringCreate database index for faster searchindex=True
copyBooleanInclude when duplicating recordcopy=False for reference numbers
trackingBoolean/IntegerLog changes in chattertracking=True
groupsStringRestrict visibility to user groupsgroups="account.group_account_manager"
company_dependentBooleanDifferent value per companycompany_dependent=True
translateBooleanCan be translated to other languagestranslate=True

Viewing Field Properties in Developer Mode

Want to see these properties for any field in Odoo? Here's how:

  1. Enable Developer Mode (Settings → bottom of page → Activate Developer Mode)
  2. Go to any form view and hover over a field label
  3. A tooltip appears showing the field's technical name
  4. Click Debug icon (bug) → View Fields to see all fields and their properties

Or via Technical menu: Settings → Technical → Database Structure → Models → find your model → Fields tab

Model vs View Properties

Same Property, Different Place

Some properties can be set in two places with different effects:

PropertyOn Model (Python)On View (XML)
requiredAlways enforced, even via APIOnly enforced in this specific view
readonlyCannot be changed via UI or code (with exceptions)Cannot be changed in this view only
invisibleN/A (use groups to hide)Hidden in this view only

Rule of thumb: Model-level properties are enforced everywhere. View-level properties only affect that specific view.

ondelete for Many2one Fields

What Happens When Linked Record Is Deleted?

ondelete ValueBehaviorUse Case
'set null'Set field to emptyOptional relationships (default)
'restrict'Prevent deletionCritical references (can't delete customer with orders)
'cascade'Delete this record tooChild records (delete order lines with order)

Company-Dependent Fields (Multi-Company)

What Are Company-Dependent Fields?

In a multi-company environment, some field values need to be different for each company. For example, a product might have different costs, accounting configurations, or warehouse settings per company.

Real-World Analogy

Think of a franchise business. The same product "Burger Meal" exists across all locations, but:

  • The price might be different in each city
  • The supplier might be different per region
  • The tax rate varies by country

Company-dependent fields solve exactly this - one record, multiple company-specific values.

How It Works Technically

When a field has company_dependent=True:

  • The value is stored as JSONB in the database with company IDs as keys
  • When you read the field, Odoo automatically returns the value for your current company
  • Fallback values can be set via ir.default (System Parameters)
python
# Database storage example:
{"1": 100.00, "2": 95.50, "3": 110.00}
# Company 1 sees: 100.00
# Company 2 sees: 95.50
# Company 3 sees: 110.00

Common Company-Dependent Fields in Odoo

LocationFieldWhy Company-Dependent?
Product → General InformationCost (standard_price)Each company may have different purchase costs for the same product
Product → AccountingIncome Account / Expense AccountEach company has its own Chart of Accounts
Product → InventoryStock Valuation AccountInventory valuation accounts differ per company
Contact → Sales & PurchaseCustomer Payment Terms / Vendor Payment TermsDifferent payment agreements per company
Contact → AccountingAccount Receivable / Account PayableDifferent receivable/payable accounts per Chart of Accounts
Contact → Sales & PurchaseFiscal PositionTax rules vary by company/country
Contact → Sales & PurchasePricelistDifferent pricing strategies per company
User PreferencesDefault WarehouseUsers work with different warehouses per company
Contact → PurchaseDelivery MethodShipping carriers vary per company location

Important for Functional Consultants

  • Always check your current company when configuring these fields
  • If a field shows different values when switching companies, it's likely company-dependent
  • Use Developer Mode → hover over field → check for "company_dependent" in technical info
  • When importing data, make sure you're in the correct company context

Properties Field (Dynamic Custom Fields)

What Is the Properties Field?

The Properties field type (added in Odoo 16/17) lets you create dynamic custom fields on the fly without modifying the database structure. Think of it as flexible "extra attributes" that can be different for each parent record.

Real-World Analogy

Imagine a Project Management system:

  • Project A (Website Redesign) needs fields: "Design Tool", "Browser Compatibility", "Mobile First?"
  • Project B (Office Move) needs fields: "Moving Company", "Insurance Policy", "Floor Plan Approved?"

With Properties, each project can have its own custom fields for tasks, without creating hundreds of unused fields in the database!

How Properties Work

Key Concept: The property definition (field names, types) is stored on the parent. The property values are stored on each child as JSON.

Container Record (e.g., Project)     →     Child Records (e.g., Tasks)
   Defines the property structure              Store only the values

Supported Property Types

TypeDescriptionExample Use
charShort textVersion number, code name
textLong textDetailed notes
htmlRich text (HTML)Formatted descriptions, instructions
integerWhole numberPriority score, count
floatDecimal numberPercentage, rating
booleanYes/No checkboxIs approved?, Is urgent?
dateDate pickerTarget date, review date
datetimeDate and timeMeeting time, deadline
selectionDropdown optionsStatus, category
tagsMultiple tagsLabels, skills required
many2oneLink to another recordAssigned vendor, related contact
many2manyMultiple linksRelated documents, team members
monetaryCurrency amountBudget, estimated cost
separatorVisual dividerGrouping properties visually

Where You'll Find Properties in Standard Odoo

  • Project Tasks - Each project can define custom properties for its tasks
  • CRM Leads - Different sales teams can have different lead attributes
  • Helpdesk Tickets - Each helpdesk team can customize ticket fields

Properties vs Traditional Custom Fields

AspectProperties FieldTraditional Custom Field
Database ImpactNo schema change (stored as JSON)Adds column to table
FlexibilityDifferent fields per parent recordSame fields for all records
Search/FilterSupported (with some limitations)Full support
ReportingLimited in standard reportsFull reporting support
Best ForFlexible, per-parent customizationConsistent fields across all records

When to Use What?

  • Use Properties when different parent records need different "child attributes" (e.g., different projects need different task fields)
  • Use Traditional Fields when ALL records need the same field (e.g., all products need a "brand" field)
  • Use Studio (Enterprise) for quick custom fields without code when Properties isn't suitable

Conditional Field Properties in Views

Properties can be set dynamically in views using conditions:

xml
<!-- Required only in certain states -->
<field name="delivery_date" required="state == 'confirmed'"/>

<!-- Readonly after confirmation -->
<field name="partner_id" readonly="state != 'draft'"/>

<!-- Invisible based on type -->
<field name="vehicle_vin" invisible="product_type != 'vehicle'"/>

Common Conditional Patterns

PatternXML AttributeUse Case
Required when confirmedrequired="state == 'confirmed'"Enforce fields at specific stages
Readonly after draftreadonly="state != 'draft'"Lock fields after workflow progress
Show for specific typeinvisible="type != 'service'"Different fields for different record types
Hide from non-managersgroups="base.group_system"Security-based visibility

Knowledge Check

Q1: What's the difference between required on model vs view?

Answer: Model-level is enforced everywhere, view-level only in that view

  • required=True in Python: Enforced via API, imports, and all views
  • required="1" in XML: Only enforced in that specific view

Use model-level for business rules that must always apply.

Q2: A field shows different values when switching companies. Why?

Answer: It's a company-dependent field

Fields with company_dependent=True store different values per company as JSONB. The value displayed depends on the user's current company context.

Q3: When should you use the Properties field type?

Answer: When different parent records need different child attributes

Properties are ideal when each project/team/category needs its own custom fields for child records, without creating unused fields across all records.

Q4: What does ondelete='restrict' do?

Answer: Prevents deletion of the linked record

If you try to delete a customer that has invoices, and the invoice's partner_id has ondelete='restrict', the deletion is blocked with an error.

Q5: How do you check a field's properties in Odoo?

Answer: Developer Mode → Debug icon → View Fields, or Settings → Technical → Fields

Enable Developer Mode, then either hover over a field and use the debug menu, or navigate to Settings → Technical → Database Structure → Fields.