10 min read

Odoo provides a rapid application development framework that’s particularly suited to building business applications. This type of application is usually concerned with keeping business records, centered around create, read, update, and delete (CRUD) operations. Not only does Odoo makes it easy to build this type of application, but it also provides rich components to create compelling user interfaces, such as kanban, calendar, and graph views.

In this tutorial, we will create list, form, and search views, the basic building blocks for the user interface.

This article is taken from the book Odoo 12 Development Essentials by Daniel Reis. This book will tecah you to build a business application from scratch by using  Odoo 12.

Technical requirements

The minimal requirement is for you to have a modern web browser, such as Firefox, Chrome, or Edge.

You may go a little further and use a packaged Odoo distribution to have it locally installed on your computer. For that, you only need an operating system such as Windows, macOS, Debian-based Linux (such as Ubuntu), or Red Hat-based Linux (such as Fedora). Windows, Debian, and Red Hat have installation packages available. Another option is to use Docker, available for all these systems and for macOS.

In this article, we will mostly have point-and-click interaction with the user interface. You will find the code snippets used and a summary of the steps performed in the book’s code repository, under the ch01 folder.

It’s important to note that Odoo databases are incompatible between Odoo major versions. If you run an Odoo 11 server against a database created for a previous major version of Odoo, it won’t work. Non-trivial migration work is needed before a database can be used with a later version of the product.

The same is true for add-on modules: as a general rule, an add-on module developed for an Odoo major version will not work on other versions. When downloading a community module from the web, make sure it targets the Odoo version you are using.

On the other hand, major releases (10.0, 11.0) are expected to receive frequent updates, but these should be mostly bug fixes. They are assured to be API-stable, meaning that model data structures and view element identifiers will remain stable. This is important because it means there will be no risk of custom modules breaking due to incompatible changes in the upstream core modules.

Creating a new Model

Models are the basic components for applications, providing the data structures and storage to be used. We will create the Model for To-do Items. It will have three fields:

  • Description
  •  Is done? flag
  • Work team partner list

Model definitions are accessed in the Settings app, in the Technical | Database Structure | Models menu.

To create a Model, follow these steps:

  1. Visit the Models menu, and click on the upper-left Create button. Fill in the new Model form with these values:
    • Model Description: To-do Item
    • Model: x_todo_item

We should save it before we can properly add new fields to it.

  1. So, click on Save and then Edit it again. You can see that a few fields were automatically added. The ORM includes them in all Models, and they can be useful for audit purposes:

The x_name (or Name) field is a title representing the record in lists or when it is referenced in other records. It makes sense to use it for the To-do Item title. You may edit it and change the Field Label to a more meaningful label description.

Adding the Is Done? flag to the Model should be straightforward now.

  1. In the Fields list, click on Add a line, at the bottom of the list, to create a new field with these values:
    • Field Name: x_is_done
    • Field Label: Is Done?
    • Field Type: boolean

The new Fields form should look like this:

Now, something a little more challenging is to add the Work Team selection. Not only it is a relation field, referring to a record in the res.partner Model, it also is a multiple-value selection field. In many frameworks, this is not a trivial task, but fortunately, that’s not the case in Odoo, because it supports many-to-many relations. This is the case because one to-do can have many people, and each person can participate in many to-do items.

  1. In the Fields list, click again on Add a line to create the new field:
    • Field Name: x_work_team_ids
    • Field Label: Work Team
    • Field Type: many2many
    • Object Relation: res.partner
    • Domain: [('x_is_work_team', '=', True)]

The many-to-many field has a few specific definitions—Relation Table, Column 1, and Column 2 fields. These are automatically filled out for you and the defaults are good for most cases, so we don’t need to worry about them now.

The domain attribute is optional, but we used it so that only eligible work team members are selectable from the list. Otherwise, all partners would be available for selection.

The Domain expression defines a filter for the records to be presented. It follows an Odoo-specific syntax—it is a list of triplets, where each triplet is a filter condition, indicating the Field Name to filter, the filter operator to use, and the value to filter against.

Odoo has an interactive domain filter wizard that can be used as a helper to generate Domain expressions. You can use it at Settings | User Interface | User-defined Filters. Once a target Model is selected in the form, the Domain field will display an add filter button, which can be used to add filter conditions, and the text box below it will dynamically show the corresponding Domain expression code.

Creating views

We have created the To-do Items Model. Next, we will be creating the two essential views for it—a list (also called a tree) and a form.

List views

We will now create a list view:

  1. In Settings, navigate to Technical | User Interface | Views and create a new record with the following values:
    • View Name: To-do List View
    • View Type: Tree
    • Model: x_todo_item

This is how the View definition is expected to look like:

  1. In the Architecture tab, we should write XML with the view structure. Use the following XML code:
<tree>
  <field name="x_name" />
  <field name="x_is_done" />
</tree>

The basic structure of a list view is quite simple—a <tree> element containing one or more <field> elements for each of the columns to display in the list view.

Form views

Next, we will create the form view:

  1. Create another View record, using the following values:
    • View Name: To-do Form View
    • View Type: Form
    • Model: x_todo_item

If we don’t specify the View Type, it will be auto-detected from the view definition.

  1. In the Architecture tab, type the following XML code:
<form>
  <group>
    <field name="x_name" />
    <field name="x_is_done" />
    <field name="x_work_team_ids" 
           widget="many2many_tags" 
           context="{'default_x_is_work_team': True}" />
  </group>
</form>

The form view structure has a root <form> element, containing elements such as <field>, Here, we also chose a specific widget for the work team field, to be displayed as tag buttons instead of a list grid.

We added the widget attribute to the Work Team field, to have the team members presented as button-like tags.

By default, relational fields allow you to directly create a new record to be used in the relationship. This means that we are allowed to create new Partner directly from the Work Team field. But if we do so, they won’t have the Is Work Team? flag enabled, which can cause inconsistencies.

For better user experience, we can have this flag set by default for these cases. This is done with the context attribute, used to pass session information to the next View, such as default values to be used. This will be discussed in detail in later chapters, and for now, we just need to know that it is a dictionary of key-value pairs. Values prefixed with default_ provide the default value for the corresponding field.

So in our case, the expression needed to set a default value for the partner’s Is Work Team? flag is {'default_x_is_work_team': True}.

That’s it. If we now try the To-Do menu option, and create a new item or open an existing one from the list, we will see the form we just added.

Search views

We can also make predefined filter and grouping options available, in the search box in the upper-right corner of the list view. Odoo considers these view elements also, and so they are defined in Views records, just like lists and forms are.

As you may already know by now, Views can be edited either in the Settings | Technical | User Interface menu, or from the contextual Developer Tools menu. Let’s go for the latter now; navigate to the to-do list, click on the Developer Tools icon in the upper-right corner, and select Edit Search view from the available options:

Since no search view is yet defined for the To-do Items Model, we will see an empty form, inviting us to create the first one. Fill in these values and save it:

  1. View Name: Some meaningful description, such as To-do Items Filter
  2. View Type: Search
  3. Model: x_todo_item
  4. Architecture: Add this XML code:
<search>
 <filter name="item_not_done" 
         string="Not Done" 
         domain="[('x_is_done', '=', False)]" />
</search>

If we now open the to-do list from the menu, so that it is reloaded, we will see that our predefined filter is now available from the Filters button below the search box. If we type Not Done inside the search box, it will also show a suggested selection.

It would be nice to have this filter enabled by default and disable it when needed. Just like default field values, we can also use context to set default filters.

When we click on the To-do menu option, it runs a Window Actions to open the To-do list view. This Window Actions can set a context value, signaling the Views to enable a search filter by default. Let’s try this:

  1. Click on the To-do menu option to go to the To-do list.
  2. Click on the Developer Tools icon and select the Edit Action option. This will open the Window Actions used to open the current Views. In the lower-right corner, there is a Filter section, where we have the Domain and Context fields.

The Domain allows setting a fixed filter on the records shown, which can’t be removed by the user. We don’t want to use that. Instead, we want to enable the item_not_done filter created before by default, which can be deselected whenever the user wishes to. To enable a filter by default, add a context key with its name prefixed with search_default_, in this case {'search_default_item_not_done': True}.

If we click on the To-do menu option now, we should see the Not Done filter enabled by default on the search box.

In this article, we created create list, form, and search views, the basic building blocks for the user interface for our model.

To learn more about Odoo development in depth, read our book Odoo 12 Development Essentials.

Read Next

“Everybody can benefit from adopting Odoo, whether you’re a small start-up or a giant tech company – An interview by Yenthe van Ginneken.

Implement an effective CRM system in Odoo 11 [Tutorial]

Handle Odoo application data with ORM API [Tutorial]

Content Marketing Editor at Packt Hub. I blog about new and upcoming tech trends ranging from Data science, Web development, Programming, Cloud & Networking, IoT, Security and Game development.