Adding data fields to a model

Models are meant to store data, and this data is structured in fields. Here, we will learn about the several types of data that can be stored in fields, and how to add them to a model.

Getting ready

This recipe assumes that you have an instance ready with the my_module addon module available, as described in Chapter 3, Creating Odoo Modules.

How to do it…

The my_module addon module should already have a models/library_book.py defining a basic Model. We will edit it to add new fields:

  1. Use the minimal syntax to add fields to the Library Books model:
    from openerp import models, fields
    class LibraryBook(models.Model):
        # ...
        short_name = fields.Char('Short Title')
        notes = fields.Text('Internal Notes')
        state = fields.Selection(
            [('draft', 'Not Available'),
             ('available', 'Available'),
             ('lost', 'Lost')],
            'State')
        description = fields.Html('Description')
        cover = fields.Binary('Book Cover')
        out_of_print = fields.Boolean('Out of Print?')
        date_release = fields.Date('Release Date')
        date_updated = fields.Datetime('Last Updated')
        pages = fields.Integer('Number of Pages')
        reader_rating = fields.Float(
            'Reader Average Rating',
            (14, 4),  # Optional precision (total, decimals),
        )
  2. All these fields support a few common attributes. As an example, we could edit the preceding pages field to add them:
        pages = fields.Integer(
            string='Number of Pages',
            default=0,
            help='Total book page count',
            groups='base.group_user',
            states={'cancel': [('readonly', True)]},
            copy=True,
            index=False,
            readonly=False,
            required=False,
            company_dependent=False,
            )
  3. The Char fields support a few specific attributes. As an example, we can edit the short_name field to add them:
        short_name = fields.Char(
            string='Short Title',
            size=100,  # For Char only
            translate=False,  # also for Text fields
            )
  4. The HTML fields also have specific attributes:
        description = fields.Html(
            string='Description',
            # optional:
            sanitize=True,
            strip_style=False,
            translate=False,
        )

Upgrading the module will make these changes effective in the Odoo model.

How it works…

Fields are added to models by defining an attribute in its Python class. The non-relational field types available are as follows:

  • Char for string values.
  • Text for multi-line string values.
  • Selection for selection lists. This has a list of values and description pairs. The value that is selected is what gets stored in the database, and it can be a string or an integer.
  • Html is similar to the Text field, but is expected to store rich text in the HTML format.
  • Binary fields store binary files, such as images or documents.
  • Boolean stores True/False values.
  • Date stores date values. The ORM handles them in the string format, but they are stored in the database as dates. The format used is defined in openerp.fields.DATE_FORMAT.
  • Datetime for date-time values. They are stored in the database in a naive date time, in UTC time. The ORM represents them as a string and also in UTC time. The format used is defined in openerp.fields.DATETIME_FORMAT.
  • Integer fields need no further explanation.
  • Float fields store numeric values. The precision can optionally be defined with a total number of digits and decimal digits pairs.
  • Monetary can store an amount in a certain currency; it is also explained in another recipe.

The first step in the recipe shows the minimal syntax to add each field type. The field definitions can be expanded to add other optional attributes, as shown in step 2.

Here is an explanation for the field attributes used:

  • string is the field's title, used in UI view labels. It actually is optional; if not set, a label will be derived from the field name by adding title case and replacing underscores with spaces.
  • size only applies to Char fields and is the maximum number of characters allowed. In general, it is advised not to use it.
  • translate when set to True, makes the field translatable; it can hold a different value depending on the user interface language.
  • default is the default value. It can also be a function that is used to calculate the default value. For example, default=_compute_default, where _compute_default is a method defined on the model before the field definition.
  • help is an explanation text displayed in the UI tooltips.
  • groups makes the field available only to some security groups. It is a string containing a comma-separated list of XML IDs for security groups. This is addressed in more detail in Chapter 10, Access Security.
  • states allows the user interface to dynamically set the value for the readonly, required, and invisible attributes, depending on the value of the state field. Therefore, it requires a state field to exist and be used in the form view (even if it is invisible).
  • copy flags if the field value is copied when the record is duplicated. By default, it is True for non-relational and Many2one fields and False for One2many and computed fields.
  • index, when set to True, makes for the creation of a database index for the field, allowing faster searches. It replaces the deprecated select=1 attribute.
  • The readonly flag makes the field read-only by default in the user interface.
  • The required flag makes the field mandatory by default in the user interface.
  • The sanitize flag is used by HTML fields and strips its content from potentially insecure tags.
  • strip_style is also an HTML field attribute and has the sanitization to also remove style elements.
  • The company_dependent flag makes the field store different values per company. It replaces the deprecated Property field type.

There's more…

The Selection field also accepts a function reference instead of a list, as its "selection" attribute. This allows for dynamically generated lists of options. You can see an example of this in the Add dynamic relations using Reference fields recipe, where a selection attribute is also used.

The Date and Datetime field objects expose a few utility methods that can be convenient.

For Date, we have the following:

  • fields.Date.from_string(string_value) parses the string into a date object.
  • fields.Date.to_string(date_value) represents the Date object as a string.
  • fields.Date.today() returns the current day in string format.
  • fields.Date.context_today(record) returns the current day in string format according to the timezone of the record's (or recordset) context.

For Datetime, we have the following:

  • fields.Datetime,from_string(string_value) parses the string into a datetime object.
  • fields.Datetime,to_string(datetime_value) represents the datetime object as a string.
  • fields.Datetime,now() returns the current day and time in string format. This is appropriate to use for default values.
  • fields.Datetime,context_timestamp(record, value) converts a value naive date-time into a timezone-aware date-time using the timezone in the context of record. This is not suitable for default values.

Other than basic fields, we also have relational fields: Many2one, One2many, and Many2many. These are explained in the Add relational fields to a model recipe.

It's also possible to have fields with automatically computed values, defining the computation function with the compute field attribute. This is explained in the Adding computed fields to a model recipe.

A few fields are added by default in Odoo models, so we should not use these names for our fields. These are the id field, for the record's automatically generated identifier, and a few audit log fields, which are as follows:

  • create_date is the record creation timestamp
  • create_uid is the user that created the record
  • write_date is the last recorded edit timestamp
  • write_uid is the user that last edited the record

The automatic creation of these log fields can be disabled by setting the _log_access=False model attribute.

Another special column that can be added to a model is active. It should be a Boolean flag allowing for mark records as inactive. Its definition looks like this:

active = fields.Boolean('Active', default=True)

By default, only records with active set to True are visible. To have them retrieved, we need to use a domain filter with [('active', '=', False)]. Alternatively, if the 'active_test': False value is added to the environment Context, the ORM will not filter out inactive records.

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

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