Odoo - Open Academy - Build an Odoo basic module ?

Zarshed Ali
Zarshed Ali
| 2 1 2
Asked on 2/26/15, 11:06 PM

Source = https://www.odoo.com/documentation/8.0/howtos/backend.html#build-an-odoo-module

Both server and client extensions are packaged as modules which are optionally loaded in a database.

Odoo modules can either add brand new business logic to an Odoo system, or alter and extend existing business logic: a module can be created to add your country’s accounting rules to Odoo’s generic accounting support, while the next module adds support for real-time visualisation of a bus fleet.

Everything in Odoo thus starts and ends with modules.

Composition of a module
An Odoo module can contain a number of elements:

Business objects
declared as Python classes, these resources are automatically persisted by Odoo based on their configuration
Data files
XML or CSV files declaring metadata (views or workflows), configuration data (modules parameterization), demonstration data and more
Web controllers
Handle requests from web browsers
Static web data
Images, CSS or javascript files used by the web interface or website
Module structure
Each module is a directory within a module directory. Module directories are specified by using the --addons-path option.

Tip most command-line options can also be set using a configuration file
An Odoo module is declared by its manifest. See the manifest documentation information about it.

A module is also a Python package with a __init__.py file, containing import instructions for various Python files in the module.

For instance, if the module has a single mymodule.py file __init__.py might contain:

from . import mymodule
Odoo provides a mechanism to help set up a new module, odoo.py has a subcommand scaffold to create an empty module:

$ odoo.py scaffold <module name> <where to put it>
The command creates a subdirectory for your module, and automatically creates a bunch of standard files for a module. Most of them simply contain commented code or XML. The usage of most of those files will be explained along this tutorial.

Exercise Module creation
Use the command line above to create an empty module Open Academy, and install it in Odoo.

Invoke the command odoo.py scaffold openacademy addons.
Adapt the manifest file to your module.
Don’t bother about the other files.
# -*- coding: utf-8 -*-
    'name': "Open Academy",

    'summary': """Manage trainings""",

    'description': """
        Open Academy module for managing trainings:
            - training courses
            - training sessions
            - attendees registration

    'author': "Your Company",
    'website': "http://www.yourcompany.com",

    # Categories can be used to filter modules in modules listing
    # Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml
    # for the full list
    'category': 'Test',
    'version': '0.1',

    # any module necessary for this one to work correctly
    'depends': ['base'],

    # always loaded
    'data': [
        # 'security/ir.model.access.csv',
    # only loaded in demonstration mode
    'demo': [
# -*- coding: utf-8 -*-
from . import controllers
from . import models
# -*- coding: utf-8 -*-
from openerp import http

# class Openacademy(http.Controller):
#     @http.route('/openacademy/openacademy/', auth='public')
#     def index(self, **kw):
#         return "Hello, world"

#     @http.route('/openacademy/openacademy/objects/', auth='public')
#     def list(self, **kw):
#         return http.request.render('openacademy.listing', {
#             'root': '/openacademy/openacademy',
#             'objects': http.request.env['openacademy.openacademy'].search([]),
#         })

#     @http.route('/openacademy/openacademy/objects/<model("openacademy.openacademy"):obj>/', auth='public')
#     def object(self, obj, **kw):
#         return http.request.render('openacademy.object', {
#             'object': obj
#         })
        <!--  -->
        <!--   <record id="object0" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 0</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object1" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 1</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object2" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 2</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object3" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 3</field> -->
        <!--   </record> -->
        <!--  -->
        <!--   <record id="object4" model="openacademy.openacademy"> -->
        <!--     <field name="name">Object 4</field> -->
        <!--   </record> -->
        <!--  -->
# -*- coding: utf-8 -*-

from openerp import models, fields, api

# class openacademy(models.Model):
#     _name = 'openacademy.openacademy'

#     name = fields.Char()
        <!-- <template id="listing"> -->
        <!--   <ul> -->
        <!--     <li t-foreach="objects" t-as="object"> -->
        <!--       <a t-attf-href="{{ root }}/objects/{{ object.id }}"> -->
        <!--         <t t-esc="object.display_name"/> -->
        <!--       </a> -->
        <!--     </li> -->
        <!--   </ul> -->
        <!-- </template> -->
        <!-- <template id="object"> -->
        <!--   <h1><t t-esc="object.display_name"/></h1> -->
        <!--   <dl> -->
        <!--     <t t-foreach="object._fields" t-as="field"> -->
        <!--       <dt><t t-esc="field"/></dt> -->
        <!--       <dd><t t-esc="object[field]"/></dd> -->
        <!--     </t> -->
        <!--   </dl> -->
        <!-- </template> -->
Object-Relational Mapping
A key component of Odoo is the ORM layer. This layer avoids having to write most SQL by hand and provides extensibility and security services[2].

Business objects are declared as Python classes extending Model which integrates them into the automated persistence system.

Models can be configured by setting a number of attributes at their definition. The most important attribute is _name which is required and defines the name for the model in the Odoo system. Here is a minimally complete definition of a model:

from openerp import models
class MinimalModel(models.Model):
    _name = 'test.model'
Model fields
Fields are used to define what the model can store and where. Fields are defined as attributes on the model class:

from openerp import models, fields

class LessMinimalModel(models.Model):
    _name = 'test.model2'

    name = fields.Char()
Common Attributes

Much like the model itself, its fields can be configured, by passing configuration attributes as parameters:

name = field.Char(required=True)
Some attributes are available on all fields, here are the most common ones:

string (unicode, default: field’s name)
The label of the field in UI (visible by users).
required (bool, default: False)
If True, the field can not be empty, it must either have a default value or always be given a value when creating a record.
help (unicode, default: '')
Long-form, provides a help tooltip to users in the UI.
index (bool, default: False)
Requests that Odoo create a database index on the column
Simple fields

There are two broad categories of fields: “simple” fields which are atomic values stored directly in the model’s table and “relational” fields linking records (of the same model or of different models).

Example of simple fields are Boolean, Date, Char.

Reserved fields

Odoo creates a few fields in all models[1]. These fields are managed by the system and shouldn’t be written to. They can be read if useful or necessary:

id (Id)
the unique identifier for a record in its model
create_date (Datetime)
creation date of the record
create_uid (Many2one)
user who created the record
write_date (Datetime)
last modification date of the record
write_uid (Many2one)
user who last modified the record
Special fields

By default, Odoo also requires a name field on all models for various display and search behaviors. The field used for these purposes can be overridden by setting _rec_name.

Exercise Define a model
Define a new data model Course in the openacademy module. A course has a title and a description. Courses must have a title.

Edit the file openacademy/models.py to include a Course class.

from openerp import models, fields, api

class Course(models.Model):
    _name = 'openacademy.course'

    name = fields.Char(string="Title", required=True)
    description = fields.Text()
Data files
Odoo is a highly data driven system. Although behavior is customized using Python code part of a module’s value is in the data it sets up when loaded.

Tip some modules exist solely to add data into Odoo
Module data is declared via data files, XML files with <record> elements. Each <record> element creates or updates a database record.

        <record model="{model name}" id="{record identifier}">
            <field name="{a field name}">{a value}</field>
model is the name of the Odoo model for the record
id is an external identifier, it allows referring to the record (without having to know its in-database identifier)
<field> elements have a name which is the name of the field in the model (e.g. description). Their body is the field’s value.
Data files have to be declared in the manifest file to be loaded, they can be declared in the 'data' list (always loaded) or in the 'demo' list (only loaded in demonstration mode).

Exercise Define demonstration data
Create demonstration data filling the Courses model with a few demonstration courses.

Edit the file openacademy/demo.xml to include some data.

        <record model="openacademy.course" id="course0">
            <field name="name">Course 0</field>
            <field name="description">Course 0's description

Can have multiple lines
        <record model="openacademy.course" id="course1">
            <field name="name">Course 1</field>
            <!-- no description for this one -->
        <record model="openacademy.course" id="course2">
            <field name="name">Course 2</field>
            <field name="description">Course 2's description</field>
Actions and Menus
Actions and menus are regular records in database, usually declared through data files. Actions can be triggered in three ways:

by clicking on menu items (linked to specific actions)
by clicking on buttons in views (if these are connected to actions)
as contextual actions on object
Because menus are somewhat complex to declare there is a <menuitem> shortcut to declare an ir.ui.menu and connect it to the corresponding action more easily.

<record model="ir.actions.act_window" id="action_list_ideas">
    <field name="name">Ideas</field>
    <field name="res_model">idea.idea</field>
    <field name="view_mode">tree,form</field>
<menuitem id="menu_ideas" parent="menu_root" name="Ideas" sequence="10"
Danger The action must be declared before its corresponding menu in the XML file.
Data files are executed sequentially, the action’s id must be present in the database before the menu can be created.
Exercise Define new menu entries
Define new menu entries to access courses and sessions under the OpenAcademy menu entry. A user should be able to

display a list of all the courses
create/modify courses
Create openacademy/views/openacademy.xml with an action and the menus triggering the action
Add it to the data list of openacademy/__openerp__.py
    'data': [
        # 'security/ir.model.access.csv',
    # only loaded in demonstration mode
    'demo': [
<?xml version="1.0" encoding="UTF-8"?>
        <!-- window action -->
            The following tag is an action definition for a "window action",
            that is an action opening a view or a set of views
        <record model="ir.actions.act_window" id="course_list_action">
            <field name="name">Courses</field>
            <field name="res_model">openacademy.course</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="help" type="html">
                <p class="oe_view_nocontent_create">Create the first course

        <!-- top level menu: no parent -->
        <menuitem id="main_openacademy_menu" name="Open Academy"/>
        <!-- A first level in the left side menu is needed
             before using action= attribute -->
        <menuitem id="openacademy_menu" name="Open Academy"
        <!-- the following menuitem should appear *after*
             its parent openacademy_menu and *after* its
             action course_list_action -->
        <menuitem id="courses_menu" name="Courses" parent="openacademy_menu"
        <!-- Full id location:
             It is not required when it is the same module -->

Zarshed Ali
Zarshed Ali
| 2 1 2
Answered on 2/26/15, 11:07 PM

Your answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

Ask a Question

Keep Informed

About This Forum

This forum is for HiTechnologia Employees & just Odoo general knowledge purpose only.

Read Guidelines

Question tools

2 follower(s)


Asked: 2/26/15, 11:06 PM
Seen: 11982 times
Last updated: 2/26/15, 11:10 PM