Implementing Constraints and Validations in Odoo 19 Models with Regular Expressions

December 9, 2025 by
Implementing Constraints and Validations in Odoo 19 Models with Regular Expressions
Jasson
| No comments yet

Data integrity is crucial in any business application. Odoo 19 provides robust mechanisms to enforce constraints and validations on your models, ensuring that only valid data enters your database. This article explores the different types of constraints available in Odoo 19 and demonstrates how to implement them effectively, including the use of regular expressions for advanced pattern matching.


Types of Constraints in Odoo


1. SQL Constraints

SQL constraints are defined at the database level and are enforced by PostgreSQL. They are the fastest type of constraint but offer limited flexibility.

from odoo import models, fields 
class Partner(models.Model):
    _name = 'res.partner'
    _inherit = 'res.partner'
    
    email = fields.Char(string='Email')
    
    _sql_constraints = [
        ('email_unique', 'UNIQUE(email)', 'Email address must be unique!'),
        ('check_credit_limit', 'CHECK(credit_limit >= 0)', 'Credit limit cannot be negative!')
    ]


2. Python Constraints

Python constraints use the @api.constrains decorator and provide more flexibility for complex validation logic. They are executed when the specified fields are modified.

@api.constrains('list_price', 'standard_price')
def _check_price(self):   
for record in self:
if record.list_price < record.standard_price:
raise ValidationError("Sales price must not be less than cost!")


Using Regular Expression


Regular expressions (regex) are powerful tools for pattern matching and validation. They are particularly useful for validating formats like email addresses, phone numbers, postal codes, and other structured data.

Python's re module provides comprehensive support for regular expressions. Here are the key concepts:

Basic Patterns

  • . - Matches any single character except newline
  • ^ - Matches the start of the string
  • $ - Matches the end of the string
  • * - Matches 0 or more repetitions
  • + - Matches 1 or more repetitions
  • ? - Matches 0 or 1 repetition
  • {m,n} - Matches from m to n repetitions
  • [] - Matches any single character within brackets
  • | - OR operator
  • () - Groups patterns together

Character Classes

  • \d - Matches any digit (equivalent to [0-9])
  • \D - Matches any non-digit
  • \w - Matches any word character (letters, digits, underscore)
  • \W - Matches any non-word character
  • \s - Matches any whitespace character
  • \S - Matches any non-whitespace character


Examples:

import re
from odoo import models, fields, api
from odoo.exceptions import ValidationError

class Partner(models.Model):
    _inherit = 'res.partner'
   
    @api.constrains('email')
    def _check_email_format(self):
        email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        for record in self:
            if record.email and not re.match(email_pattern, record.email):
                raise ValidationError(
                    f"Invalid email format: {record.email}\n"
                    "Please enter a valid email address."
                )


Conclusion


Implementing proper constraints and validations is essential for maintaining data quality in your Odoo applications. By combining SQL constraints for basic checks, Python constraints for complex business logic, and regular expressions for pattern matching, you can create robust and reliable models.

Regular expressions provide powerful pattern matching capabilities, but they should be used judiciously. Always test your patterns thoroughly, provide clear error messages, and document complex patterns for future maintenance.

Remember to balance validation strictness with user experience—overly restrictive validations can frustrate users, while too lenient validations can compromise data integrity. Find the right balance for your specific business requirements.


Implementing Constraints and Validations in Odoo 19 Models with Regular Expressions
Jasson December 9, 2025
Share this post
Archive
Sign in to leave a comment