To enforce data integrity, models also support two types of constraints: SQL and Python.
SQL constraints are added to the table definition in the database and implemented by PostgreSQL. They are defined using the class attribute _sql_constraints
. It is a list of tuples with the constraint identifier name, the SQL for the constraint, and the error message to use.
A common use case is to add unique constraints to models. Suppose we didn't want to allow the same user to have two active tasks with the same title:
# class TodoTask(models.Model): _sql_constraints = [ ('todo_task_name_uniq', 'UNIQUE (name, user_id, active)', 'Task title must be unique!')]
Since we are using the user_id
field added by the todo_user
module, this dependency should be added to the depends
key of the __openerp__.py
manifest file.
Python constraints can use a piece of arbitrary code to check conditions. The checking function needs to be decorated with @api.constrains
indicating the list of fields involved in the check. The validation is triggered when any of them is modified, and will raise an exception if the condition fails:
from openerp.exceptions import ValidationError # class TodoTask(models.Model): @api.one @api.constrains('name') def _check_name_size(self): if len(self.name) < 5: raise ValidationError('Must have 5 chars!')
The preceding example prevents saving task titles with less than 5 characters.