Adding constraint validations to a Model

Models can have validations preventing them from entering undesired conditions. Two different types of constraint can be used: the ones checked at the database level and the ones checked at the server level.

Database level constraints are limited to the constraints supported by PostgreSQL. The most commonly used are the UNIQUE constraints, but CHECK and EXCLUDE constraints can also be used. If these are not enough for our needs, we can use Odoo server level constraints, written in Python code.

We will use the Library Book model created in Chapter 3, Creating Odoo Modules and add a couple of constraints to it. We will add a database constraint preventing duplicate book titles, and a Python model constraint preventing release dates in the future.

Getting ready

We will reuse the my_module addon module from Chapter 3, Creating Odoo Modules.

We expect it to contain at least the following:

# -*- coding: utf-8 -*-from openerp import models, fieldsclass LibraryBook(models.Model):_name = 'library.book'name = fields.Char('Title', required=True)date_release = fields.Date('Release Date')

How to do it…

We will edit the LibraryBook class in the models/library_book_categ.py Python file:

  1. To create the database constraint, add a model attribute:
    class LibraryBook(models.Model):
        # ...
        _sql_constraints = [
            ('name_uniq',
             'UNIQUE (name)',
             'Book title must be unique.')
            ]
  2. To create the Python code constraint, add a model method:
    from openerp import api
    class LibraryBook(models.Model):
        # ...
        @api.constrains('date_release')
        def _check_release_date(self):
            for r in self:
                if r.date_release > fields.Date.today():
                    raise models.ValidationError(
                        'Release date must be in the past')
    

After these changes are made to the code file, an addon module upgrade and server restart are needed.

How it works…

The first step has a database constraint created on the model's table. It is enforced at the database level. The _sql_constraints model attribute accepts a list of constraints to create. Each constraint is defined by a three element tuple; they are listed as follows:

  • A suffix to use for the constraint identifier. In our example, we used name_uniq and the resulting constraint name is library_book_name_uniq.
  • The SQL to use in the PostgreSQL instruction to alter or create the database table.
  • A message to report to the user when the constraint is violated.

As mentioned earlier, other database table constraints can be used. Note that column constraints, such as NOT NULL, can't be added this way. For more information on PostgreSQL constraints in general and table constraints in particular, take a look at http://www.postgresql.org/docs/9.4/static/ddl-constraints.html.

In the second step, we added a method to perform a Python code validation. It is decorated with @api.constrains, meaning that it should be executed to run checks when one of the fields in the argument list is changed. If the check fails, a ValidationError exception should be raised.

Note

The _constraints model attribute is still available but has been deprecated since version 8.0. Instead, we should use methods with the new @api.constrains decorator.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.113.197