Odoo Wrapper Function: Best Practices and Use Cases

blog-banner

In Odoo 18, developers often come across advanced framework concepts that streamline the development process. One such powerful concept is the Wrapper Function by using which we can encapsulate, use and modify existing Odoo behaviors in a neat, maintainable fashion.

In this blog, we will look at what a wrapper class is, when and why you should use one, and how developers and teams offering Odoo consulting services can follow best practices when working with wrapper classes in Odoo 18.

What is a Wrapper Function in Odoo?

  • A Wrapper Function in Odoo serves as a facade that envelops the current model, method or function to provide additional or altered behavior without the need to change the original code.

  • They are typically utilized when we want to:
    • Enhance existing business functionality in an organized and reusable way.
    • Provide validation or logging around existing method.
    • Change the order of functionality of the method calls, without having to completely overhaul the original function.
  • Think of a wrapper more simply, as a decorator pattern applied to Odoo models - a method to "decorate" your function with extra functionality.

Why Use a Wrapper Function?

  • Odoo is built as a modular system and encourages extension. However, there can be reasons overriding methods directly can lead to: Code duplication. Conflicts on upgrades to modules. Difficulties debugging.
  • A Wrapper Function will let developers keep code clean and easy to maintain. Add new functionality, without changing the core. Ensure compatibility with upgrades.

  • As an example, instead of overriding the write () method on the res.partner model, all write operations can be logged extensible by wrapping the existing write () method.

Example: Creating a Wrapper Function in Odoo 18

  • Let's take a simple example where we wrap the write() method of res. partner model to log changes before write.

 
from odoo import models, api 
 
class PartnerWrapper(models.AbstractModel): 
    _name = 'partner.wrapper' 
    _description = 'Wrapper for Partner Model' 
 
    @api.model 
    def wrap_write(self, original_write): 
        """Wrapper for logging and extending write() functionality.""" 
        def wrapped_write(records, vals): 
            for rec in records: 
                _logger.info(f"[Wrapper] Updating Partner ID {rec.id} with values {vals}") 
            # Add pre-processing logic here 
            result = original_write(records, vals) 
            # Add post-processing logic here 
            _logger.info(f"[Wrapper] Successfully updated Partner ID(s): {[r.id for r in records]}") 
            return result 
        return wrapped_write 
  
  • Now, integrate this wrapper into the original model:

 
  import logging 
from odoo import models 
 
_logger = logging.getLogger(__name__) 
 
class ResPartner(models.Model): 
    _inherit = 'res.partner' 
 
    # Applying the wrapper to the original write method 
    def write(self, vals): 
        wrapper = self.env['partner.wrapper'] 
        wrapped_write = wrapper.wrap_write(super(ResPartner, self).write) 
        return wrapped_write(self, vals) 
  

Output Behavior:

  • Before the write operation → logs the changes to be applied.
  • After the write operation → Indicate that this was successful.
  • That way you can add logic around existing methods on the fly, without completely overwriting them.

Common Use Cases

Here are some of the use cases in real time where Wrapper Classes are very useful:

Use Case

Description

Logging

Log before and after CRUD operations without cluttering our core code.

Performance Tracking

Measure time, before and after, for any of our important methods.

Validation Layer

Create validations prior to saving or removing records without redeveloping the core logic.

Third-Party API Integration

Encapsulate calls to other APIs to include error handling and retry behavior.

Auditing

Record contextual information at method execution (i.e., user, date/time, record data).

Best Practices

  • Use Abstract Models: Always use models to define your wrappers as abstract models to reuse code across models.
  • Avoid: Don’t wrap the same method multiple times because this will cause performance issues or unexpected recursion.
  • Keep Wrapper Logic Light: If you would like your main path to run quickly, avoid heavy operations inside wrappers. Use light wrappers - just "validations", "logs", or "checks".
  • Log Clearly: Always log activity for wrapper actions - this is helpful for debugging and determining traceability.
  • Upgrade Compatibility and Safety: Utilizing wrappers will extend existing logic without removing existing logic. Wrappers should have no hard coded core logic or functional business meaning.

Wrapper Class vs Method Override

Aspect

Wrapper Function

Method Override

Purpose

Add behavior around existing logic

Replace or adjust method logic

Code Maintenance

Cleaner and modular

Could cause code conflicts

Reusability

Can apply to multiple models

Typically limited to one model

Upgrade Safety

High (no modification to core)

Medium to low (depends on depth of override)

Conclusion

Putting it together, Wrapper Function in Odoo 18 provides a way to extend current logic while keeping your custom solutions modular, clean, and upgrade-safe. Whatever logging, validation, or post-processing hooks you add, wrappers give you peace of mind by providing maintainable code that scales easily, just how professional Odoo development should be.

FAQ

1. What is a Wrapper Class?

A Wrapper Class is essentially a container around an existing method or model, to implement some new functionality, be it logging or some form of validation, without altering the original logic of the code. It is a clean and safe approach to extending the behaviors of Odoo.

2. When should I use a Wrapper Function?

Use a wrapper when you want to:

  • Implement logging or validation.
  • Measure performance or handle exceptions.
  • Extend existing functionality without breaking the original code.
  • If you only need to completely change the method of logic, then it probably makes much more sense to override it.

3. Can I use one Wrapper Function across multiple models?

Yes! If you declare your wrapper as an Abstract Model, you can reuse the wrapper across multiple models. This is one of the primary benefits of a wrapper - it helps eliminate duplicate code.

4. Will using too many wrappers slow down my system?

Not if used correctly. Wrappers should contain light logic like small checks, logs, or quick conditions. Avoid putting heavy processing or multiple nested wrappers, and your system will stay fast.

5. Can API integrations utilize Wrapper Function?

Yes, they can. Wrapper classes are perfect for managing API calls, retries and error handling all while keeping your primary logic clean and separated.

Contact us

For Your Business Requirements

Contact us