Skip to Content

The product.product Model: Understanding Odoo's Product Variant Architecture

A complete guide to Odoo's product variant model for developers and functional consultants
March 10, 2026 by
The product.product Model: Understanding Odoo's Product Variant Architecture
Dasolo
| No comments yet

Introduction


In Odoo, models define how data is structured and stored in the database. Every piece of business data you work with, from sales orders to inventory to products, lives in a model.


Understanding Odoo models is essential for both developers and functional consultants. Models are the foundation of the Odoo data architecture. They define Odoo fields, relationships, and business logic.


This article focuses on one of the most important models in Odoo: product.product. Whether you are building custom modules, integrating external systems, or configuring product catalogs, you will work with this model.

What is the product.product Model


The product.product model represents the actual product variants in Odoo. These are the concrete, sellable and purchasable items that appear on sales orders, purchase orders, and inventory moves.


This model in Odoo is different from product.template. The template holds shared attributes for a product family. The product.product records are the specific variants. For a simple product with no variants, there is one product.product per product.template. For configurable products (e.g. T-shirt with size and color), each combination is a separate product.product.


The model is defined in the product module (product). Sales, Purchase, Inventory, and e-commerce all reference product.product. When you add a line to a quotation or receive stock, you work with product.product records.


product.product uses delegation inheritance from product.template. Many Odoo fields are defined on the template and inherited by the variant. This keeps shared data in one place while allowing variant-specific overrides.

Key Fields in the Model


Here are the most important Odoo fields in the product.product model. Understanding these will help you work effectively with product variants.


1. name

Type: Char. This field stores the name of the product variant. It is typically displayed in lists, forms, and documents. For simple products it matches the template name. For variants it may include attribute values (e.g. "T-Shirt - Blue / M").


2. product_tmpl_id

Type: Many2one (product.template). Links the variant to its parent template. This is the core relationship. Every product.product belongs to exactly one product.template. Use this when you need to inherit model in Odoo or extend product logic.


3. default_code

Type: Char. Internal reference or SKU. Used for identification, barcode lookup, and integration with external systems. Each variant can have its own code.


4. barcode

Type: Char. Barcode (EAN, UPC, etc.). Used for scanning in POS, warehouse, and inventory. Must be unique across products when set.


5. create_date

Type: Datetime. Stores the date and time when the record was created. Automatically managed by Odoo. Useful for reporting and auditing.


6. write_date

Type: Datetime. Stores the date and time of the last modification. Also automatically managed. Helps track when data was last updated.


7. active

Type: Boolean. Soft delete flag. When False, the record is archived and hidden from default views. Products are not physically deleted to preserve history.


8. type

Type: Selection. Product type: Consumable, Service, or Storable Product. Consumables are not tracked in inventory. Services have no stock. Storable products are tracked in stock. This drives which modules and workflows apply.


9. categ_id

Type: Many2one (product.category). The product category. Used for reporting, pricing rules, and catalog organization. Categories can have parent-child hierarchy.


10. list_price

Type: Float. The sales price. Displayed on quotations and used as default when adding a line. Can be overridden per customer or by pricelists.


11. standard_price

Type: Float. The cost price. Used for inventory valuation and margin calculations. Typically updated by purchase orders or manual entry.


12. uom_id

Type: Many2one (uom.uom). Unit of measure for sales and inventory. Defines how quantities are expressed (units, kg, liters, etc.).


13. uom_po_id

Type: Many2one (uom.uom). Unit of measure for purchases. Can differ from uom_id (e.g. buy in boxes, sell in units). Conversion is handled automatically.


14. description_sale

Type: Html. Sales description. Shown on quotations, orders, and invoices. Can include formatting and product details.


15. description_purchase

Type: Html. Purchase description. Shown on purchase orders and vendor bills. Used for internal and vendor communication.


16. sale_ok

Type: Boolean. Can be sold. When False, the product is hidden from sales and e-commerce. Useful for internal or purchase-only items.


17. purchase_ok

Type: Boolean. Can be purchased. When False, the product is hidden from purchase. Useful for manufactured or sales-only items.


18. image_1920

Type: Binary. Product image at full resolution. Odoo stores multiple sizes (image_512, image_256, etc.) for display. Used in forms, e-commerce, and reports.


19. weight

Type: Float. Product weight. Used for shipping calculations and logistics. Unit depends on company configuration.


20. volume

Type: Float. Product volume. Used for shipping and warehouse capacity. Important for businesses with volumetric constraints.


21. company_id

Type: Many2one (res.company). In multi-company setups, this indicates which company owns the product. Affects record visibility and stock.


22. currency_id

Type: Many2one (res.currency). Currency for list_price and standard_price. Usually the company currency. Pricelists can convert to other currencies.


23. qty_available

Type: Float. Quantity on hand. Computed from stock quants. Read-only. Used for availability checks and reports. Only for storable products.


24. virtual_available

Type: Float. Forecasted quantity (on hand plus incoming minus outgoing). Used for availability and replenishment. Read-only computed field.


25. product_template_attribute_value_ids

Type: Many2many. Links to the attribute values that define this variant (e.g. Color=Blue, Size=M). Used for variant configuration and filtering.


26. sequence

Type: Integer. Display order. Used to sort products in lists and configurators. Lower values appear first.


27. display_name

Type: Char. Computed display name. Combines name with variant attributes. Used in many2one dropdowns and search results. Read-only.


28. responsible_id

Type: Many2one (res.users). Responsible person for the product. Used for reordering rules and internal assignment. Optional.

How This Model Is Used in Business Workflows


1. Sales and Quotations

When a salesperson creates a quotation, they select a product.product from the catalog. The list_price, description_sale, and uom_id flow to the order line. Pricelists can override the price. Only products with sale_ok=True appear.


2. Purchase and Vendors

Purchase orders and vendor bills reference product.product. The standard_price is updated from purchase costs. Products with purchase_ok=True are available. The uom_po_id defines how quantities are ordered (e.g. by box).


3. Inventory and Stock

Stock moves, pickings, and quants all use product.product. The qty_available and virtual_available fields drive availability. Only storable products are tracked. Barcode scanning uses the barcode field for fast lookup.


4. E-commerce and Website

The website shop displays product.product records. Variants with different attributes (size, color) are shown as options. Product images, descriptions, and prices come from the model. The sale_ok flag controls visibility.


5. Manufacturing and MRP

Bills of materials reference product.product for both components and finished goods. The type field determines if a product is manufactured (storable) or consumed. Stock levels drive production planning.

How Developers Extend This Model


Developers extend product.product using several patterns. Odoo model inheritance is the main mechanism.


Model Inheritance

Use _inherit = 'product.product' to extend the model. Add new Odoo fields, override methods, or add constraints. The inherit model in Odoo keeps your changes in a separate module for easy upgrades. Choose product.product when the field is variant-specific; use product.template when it applies to the whole product family.


Adding Fields

Define new Odoo fields in your inherited model. Use the right field type: Char, Many2one, Boolean, Integer, Text, Selection. Consider whether the field belongs on the template (shared) or the variant (specific). For variant-specific data like SKU or barcode overrides, use product.product.


Python Extensions

Override create, write, or unlink to add logic. Use super() to call the original. Be careful with computed fields and their dependencies. The product.product model has many computed fields from stock and sale modules.


Odoo Studio

Odoo Studio lets you add fields without code. Good for quick customizations. For complex logic or upgrades, custom modules are more maintainable. The API model in Odoo (product.product) is fully exposed via XML-RPC and JSON-RPC for integrations.

Best Practices


  • Use default_code or barcode for external system mapping. Keep them unique and consistent.
  • Set type correctly for each product. Consumable vs Storable vs Service affects which modules and workflows apply.
  • When building API integrations, use product.product for order lines and transactions. Use product.template for catalog-level operations.
  • For custom fields, use the x_ prefix or a module prefix to avoid conflicts with future Odoo versions.
  • Consider product.template when adding fields that apply to all variants (e.g. brand, category). Use product.product for variant-specific data (e.g. variant-specific barcode).

Common Mistakes


  • Inheriting from product.template when you need variant-specific logic. Use product.product for per-variant behavior.
  • Creating product.product records manually instead of through the template. For variant products, create them via the product configurator.
  • Forgetting to set sale_ok or purchase_ok. Products are hidden from sales/purchase by default in some configurations.
  • Overriding core methods without calling super(). This can break other modules or future upgrades.
  • Using product.product in domains when product.template would be more appropriate (e.g. filtering by category on the template).

Conclusion


The product.product model is central to Odoo's product architecture. It represents the actual sellable and purchasable items. Understanding its fields and how it relates to product.template will help you configure, customize, and integrate Odoo effectively.


Whether you are a functional consultant mapping product catalogs or a developer building custom modules, a solid grasp of product.product will save time and prevent errors.

Need Help With Your Odoo Implementation ?


Dasolo helps companies implement, customize, and optimize Odoo. We specialize in API integrations and Odoo development. Our team has deep experience with the Odoo data architecture and models like product.product.


If you need help with your Odoo implementation, custom modules, or integrations, we are here to help. Book a demo to discuss your project.

The product.product Model: Understanding Odoo's Product Variant Architecture
Dasolo March 10, 2026
Share this post
Sign in to leave a comment