After creating a new model, the next step is to add fields to it. Let's explore the several types of fields available in Odoo.
We now have a Stage
model and will expand it to add some additional fields. We should edit the todo_ui/todo_model.py
file, by removing some unnecessary attributes included before for the purpose of explanation, making it look like this:
class Stage(models.Model): _name = 'todo.task.stage' _order = 'sequence,name' # String fields: name = fields.Char('Name', 40) desc = fields.Text('Description') state = fields.Selection( [('draft','New'), ('open','Started'),('done','Closed')], 'State') docs = fields.Html('Documentation') # Numeric fields: sequence = fields.Integer('Sequence') perc_complete = fields.Float('% Complete', (3, 2)) # Date fields: date_effective = fields.Date('Effective Date') date_changed = fields.Datetime('Last Changed') # Other fields: fold = fields.Boolean('Folded?') image = fields.Binary('Image')
Here, we have a sample of the non-relational field types available in Odoo, with the basic arguments expected by each function. For most, the first argument is the field title, corresponding to the string
keyword attribute. It's an optional argument, but it is recommended to be provided. If not, a title will be automatically generated from the field name.
There is a convention for date fields to use date
as a prefix in their name. For example, we should use date_effective
instead of effective_date
. This can also apply to other fields, such as amount_
, price_
or qty_
.
A few more arguments are available for most field types:
Char
accepts a second, optional argument, size
, corresponding to the maximum text size. It's recommended to use it only if you have a good reason to.Text
differs from Char
in that it can hold multiline text content, but expects the same arguments.Selection
is a drop-down selection list. The first argument is the list of selectable options and the second is the title string. The selection list items are ('value', 'Title')
tuples for the value stored in the database and the corresponding description string. When extending through inheritance, the selection_add
argument can be used to append items to an existing selection list.Html
is stored as a text field, but has specific handling to present HTML content on the user interface.Integer
just expects a string argument for the field title.Float
has a second optional argument, an (x,y)
tuple with the field's precision: x
is the total number of digits; of those, y
are decimal digits.Date
and Datetime
data is stored in UTC time. There are automatic conversions made, based on the user time zone preferences, made available through the user session context. This is discussed in more detail in Chapter 6, Views – Designing the User Interface.Boolean
only expects the field title to be set, even if it is optional.Binary
also expects only a title argument.Other than these, we also have the relational fields, which will be introduced later in this chapter. But now, there is still more to learn about these field types and their attributes.
Fields also have a set of attributes we can use, and we'll explain these in more detail:
string
is the field title, used as its label in the UI. Most of the time it is not used as a keyword argument, since it can be set as a positional argument.default
sets a default value for the field. It can be a static value or a callable, either a function reference or a lambda expression.size
applies only to Char
fields, and can set a maximum size allowed.translate
applies to text fields, Char
, Text
and Html
, and makes the field translatable: it can have different values for different languages.help
provides the text for tooltips displayed to the users.readonly=True
makes the field not editable on the user interface.required=True
makes the field mandatory.index=True
will create a database index on the field.copy=False
has the field ignored when using the copy function. The non-relational fields are copyable by default.groups
allows limiting the field's access and visibility to only some groups. It is a comma-separated list of strings for security group XML IDs.states
expects a dictionary mapping values for UI attributes depending on values of the state
field. For example: states={'done':[('readonly',True)]}
. Attributes that can be used are readonly
, required
, and invisible
. For completeness, two other attributes are sometimes used when upgrading between Odoo major versions:
A few field names are reserved to be used by the ORM:
The following fields are automatically created on new models, unless the _log_access=False
model attribute is set:
create_uid
for the user that created the recordcreate_date
for the date and time when the record is createdwrite_uid
for the last user to modify the recordwrite_date
for the last date and time when the record was modifiedThis information is available from the web client, using the Developer Mode menu and selecting the View Metadata option.
There some built-in effects that expect specific field names. We should avoid using them for purposes other than the intended ones. Some of them are even reserved and can't be used for other purposes at all:
name
is used by default as the display name for the record. Usually it is a Char
, but other field types are also allowed. It can be overridden by setting the _rec_name
model attribute.active
(type Boolean
) allows inactivating records. Records with active==False
will automatically be excluded from queries. To access them an ('active','=',False)
condition must be added to the search domain, or 'active_test': False
should be added to the current context.sequence
(type Integer
) if present in a list view, allows to manually define the order of the records. To work properly it should also be in the model's _order
.state
(type Selection
) represents basic states of the record's life cycle, and can be used by the state's field attribute to dynamically modify the view: some form fields can be made read only, required or invisible in specific record states.parent_id
, parent_left
, and parent_right
have special meaning for parent/child hierarchical relations. We will shortly discuss them in detail.So far we've discussed scalar value fields. But a good part of an application data structure is about describing the relationships between entities. Let's look at that now.