Skip to content

File Creator

The File Creator lets you instantly generate specific Odoo files—Python, XML, and CSV—with pre-filled, context-aware templates tailored for Odoo modules. This feature helps you maintain consistency and follow best practices while reducing boilerplate code.

How to Use

  1. Right-click on the folder where you want the new file
  2. Select New → New Odoo File
  3. Choose the file type: Python, XML, or CSV
  4. Select the desired content template
  5. Name the file and press Enter

Supported File Types & Templates

Python Files

TemplateDescription
__init__.pyBasic initialization file with encoding and import placeholders
__manifest__.pyModule manifest with metadata and dependencies
Odoo ModelModel definition with fields and methods
Odoo ControllerHTTP controller with routes and endpoints

XML Files

TemplateDescription
Empty ViewBlank XML file for custom configurations
Basic ViewMinimal form and list view definitions
Advanced ViewComplex views with groups, notebooks, and statusbars
Inherit ViewView inheritance and extension using xpath
Report ViewQWeb report templates and actions
Security Group ViewUser groups and access rights
Security Rule ViewRecord-level access control rules
Sequence ViewSequence definition for automatic numbering
Settings ViewSettings form definition for configuration
Cron Job ViewScheduled action definition for automation

CSV Files

TemplateDescription
Security AccessModel access rights by group (ir.model.access.csv)

Template Examples

Python Files

__init__.py

python
# -*- coding: utf-8 -*-
from . import

__manifest__.py

python
# -*- coding: utf-8 -*-
{
    'name': 'Module Name',
    'version': '1.0',
    'category': 'Uncategorized',
    'summary': 'Module Summary',
    'description': '''Module Description''',
    'author': 'Your Company',
    'website': 'https://www.yourcompany.com',
    'depends': ['base'],
    'data': [
        'security/ir.model.access.csv',
        'views/views.xml',
    ],
    'installable': True,
    'application': False,
    'auto_install': False,
}

Odoo Model

python
# -*- coding: utf-8 -*-
from odoo import fields,models

class ModelName(models.Model):
    _name = 'model.name'

    name = fields.Char(string='Name')

Odoo Controller

python
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request


class ContollerController(http.Controller):
    """Controller class to handle HTTP routes."""
    @http.route('/contoller', auth='public', website=True)
    def index(self, **kw):
        return request.render('your_module.template_id', {'sample_data': 'Sample Data'})

XML Files

Empty View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Your custom views here -->
    </data>
</odoo>

Basic View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Form View -->
        <record id="model_name_form" model="ir.ui.view">
            <field name="name">model.name.form</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <form string="Model Name">
                    <sheet>
                        <group>
                            <field name="name"/>
                            <!-- Add your fields here -->
                        </group>
                    </sheet>
                </form>
            </field>
        </record>
        
        <!-- List View -->
        <record id="model_name_list" model="ir.ui.view">
            <field name="name">model.name.list</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <list string="Model Name">
                    <field name="name"/>
                    <!-- Add your fields here -->
                </list>
            </field>
        </record>
        
        <!-- Action -->
        <record id="action_model_name" model="ir.actions.act_window">
            <field name="name">Model Name</field>
            <field name="res_model">model.name</field>
            <field name="view_mode">list,form</field>
            <field name="help" type="html">
                <p class="o_view_nocontent_smiling_face">
                    Create your first model name!
                </p>
            </field>
        </record>
        
        <!-- Menu -->
        <menuitem id="menu_model_name"
                  name="Model Name"
                  action="action_model_name"
                  sequence="10"/>
    </data>
</odoo>

Advanced View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Form View -->
        <record id="model_name_form" model="ir.ui.view">
            <field name="name">model.name.form</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <form string="Model Name">
                    <header>
                        <button name="action_confirm" string="Confirm" type="object" class="oe_highlight"/>
                        <button name="action_cancel" string="Cancel" type="object"/>
                        <field name="state" widget="statusbar" statusbar_visible="draft,confirmed,done"/>
                    </header>
                    <sheet>
                        <div class="oe_title">
                            <h1>
                                <field name="name"/>
                            </h1>
                        </div>
                        <notebook>
                            <page string="General Information">
                                <group>
                                    <group>
                                        <field name="field1"/>
                                        <field name="field2"/>
                                    </group>
                                    <group>
                                        <field name="field3"/>
                                        <field name="field4"/>
                                    </group>
                                </group>
                            </page>
                            <page string="Lines">
                                <field name="line_ids">
                                    <list editable="bottom">
                                        <field name="name"/>
                                        <field name="description"/>
                                        <field name="quantity"/>
                                        <field name="price"/>
                                        <field name="subtotal" sum="Total"/>
                                    </list>
                                </field>
                            </page>
                            <page string="Notes">
                                <field name="notes"/>
                            </page>
                        </notebook>
                    </sheet>
                    <chatter/>
                </form>
            </field>
        </record>
        
        <!-- List View -->
        <record id="model_name_list" model="ir.ui.view">
            <field name="name">model.name.list</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <list string="Model Name" decoration-info="state=='draft'" decoration-success="state=='done'" decoration-warning="state=='confirmed'">
                    <field name="name"/>
                    <field name="field1"/>
                    <field name="field2"/>
                    <field name="create_date"/>
                    <field name="state"/>
                </list>
            </field>
        </record>
        
        <!-- Search View -->
        <record id="model_name_search" model="ir.ui.view">
            <field name="name">model.name.search</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <search string="Search Model Name">
                    <field name="name"/>
                    <field name="field1"/>
                    <field name="field2"/>
                    <separator/>
                    <filter string="Draft" name="draft" domain="[('state','=','draft')]"/>
                    <filter string="Confirmed" name="confirmed" domain="[('state','=','confirmed')]"/>
                    <filter string="Done" name="done" domain="[('state','=','done')]"/>
                    <group expand="0" string="Group By">
                        <filter string="State" name="groupby_state" context="{'group_by': 'state'}"/>
                        <filter string="Creation Date" name="groupby_create_date" context="{'group_by': 'create_date:month'}"/>
                    </group>
                </search>
            </field>
        </record>
        
        <!-- Calendar View -->
        <record id="model_name_calendar" model="ir.ui.view">
            <field name="name">model.name.calendar</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <calendar string="Model Name" date_start="create_date" color="state">
                    <field name="name"/>
                    <field name="state"/>
                </calendar>
            </field>
        </record>
        
        <!-- Kanban View -->
        <record id="model_name_kanban" model="ir.ui.view">
            <field name="name">model.name.kanban</field>
            <field name="model">model.name</field>
            <field name="arch" type="xml">
                <kanban default_group_by="state" class="o_kanban_small_column" sample="1">
                    <field name="name"/>
                    <field name="state"/>
                    <field name="field1"/>
                    <field name="field2"/>
                    <templates>
                        <t t-name="kanban-box">
                            <div class="oe_kanban_global_click">
                                <div class="oe_kanban_details">
                                    <strong class="o_kanban_record_title">
                                        <field name="name"/>
                                    </strong>
                                    <div class="o_kanban_tags_section">
                                        <ul>
                                            <li><field name="field1"/></li>
                                            <li><field name="field2"/></li>
                                        </ul>
                                    </div>
                                </div>
                            </div>
                        </t>
                    </templates>
                </kanban>
            </field>
        </record>
        
        <!-- Actions -->
        <record id="action_model_name" model="ir.actions.act_window">
            <field name="name">Model Name</field>
            <field name="res_model">model.name</field>
            <field name="view_mode">list,form,kanban,calendar</field>
            <field name="search_view_id" ref="model_name_search"/>
            <field name="help" type="html">
                <p class="o_view_nocontent_smiling_face">
                    Create your first model name!
                </p>
            </field>
        </record>
        
        <!-- Menu -->
        <menuitem id="menu_model_name"
                  name="Model Name"
                  action="action_model_name"
                  sequence="10"/>
    </data>
</odoo>

Inherit View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Inherit Form View -->
        <record id="model_name_form_inherit" model="ir.ui.view">
            <field name="name">model.name.inherit.form</field>
            <field name="model">model.name</field>
            <field name="inherit_id" ref="module.original_form_view_id"/>
            <field name="arch" type="xml">
                <!-- Add fields to an existing group -->
                <xpath expr="//group[1]" position="inside">
                    <field name="new_field1"/>
                    <field name="new_field2"/>
                </xpath>
                
                <!-- Add a new page to the notebook -->
                <xpath expr="//notebook" position="inside">
                    <page string="New Page">
                        <group>
                            <field name="new_field3"/>
                            <field name="new_field4"/>
                        </group>
                    </page>
                </xpath>
                
                <!-- Modify an existing field -->
                <xpath expr="//field[@name='existing_field']" position="attributes">
                    <attribute name="readonly">1</attribute>
                    <attribute name="string">New Label</attribute>
                </xpath>
                
                <!-- Replace a field -->
                <xpath expr="//field[@name='to_replace']" position="replace">
                    <field name="replacement_field"/>
                </xpath>
                
                <!-- Add before a specific field -->
                <xpath expr="//field[@name='reference_field']" position="before">
                    <field name="before_field"/>
                </xpath>
                
                <!-- Add after a specific field -->
                <xpath expr="//field[@name='reference_field']" position="after">
                    <field name="after_field"/>
                </xpath>
            </field>
        </record>
        
        <!-- Inherit List View -->
        <record id="model_name_list_inherit" model="ir.ui.view">
            <field name="name">model.name.inherit.list</field>
            <field name="model">model.name</field>
            <field name="inherit_id" ref="module.original_list_view_id"/>
            <field name="arch" type="xml">
                <xpath expr="//field[@name='reference_field']" position="after">
                    <field name="new_field"/>
                </xpath>
            </field>
        </record>
    </data>
</odoo>

Report View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Report Action -->
        <record id="action_report_model_name" model="ir.actions.report">
            <field name="name">Model Name Report</field>
            <field name="model">model.name</field>
            <field name="report_type">qweb-pdf</field>
            <field name="report_name">model.name.report_model_name</field>
            <field name="report_file">model.name.report_model_name</field>
            <field name="binding_model_id" ref="model_model_name"/>
            <field name="binding_type">report</field>
        </record>
        
        <!-- Report Template -->
        <template id="report_model_name_document">
            <t t-call="web.external_layout">
                <t t-set="doc" t-value="doc.with_context(lang=doc.partner_id.lang)" />
                <div class="page">
                    <div class="oe_structure"/>
                    <h2>
                        <span t-field="doc.name"/>
                    </h2>
                    
                    <div class="row mt32 mb32">
                        <div class="col-auto">
                            <strong>Field 1:</strong>
                            <p t-field="doc.field1"/>
                        </div>
                        <div class="col-auto">
                            <strong>Field 2:</strong>
                            <p t-field="doc.field2"/>
                        </div>
                        <div class="col-auto">
                            <strong>Date:</strong>
                            <p t-field="doc.create_date"/>
                        </div>
                    </div>
                    
                    <table class="table table-sm o_main_table">
                        <thead>
                            <tr>
                                <th name="th_description" class="text-left">Description</th>
                                <th name="th_quantity" class="text-right">Quantity</th>
                                <th name="th_price" class="text-right">Price</th>
                                <th name="th_subtotal" class="text-right">Subtotal</th>
                            </tr>
                        </thead>
                        <tbody>
                            <t t-foreach="doc.line_ids" t-as="line">
                                <tr>
                                    <td name="td_description"><span t-field="line.description"/></td>
                                    <td name="td_quantity" class="text-right"><span t-field="line.quantity"/></td>
                                    <td name="td_price" class="text-right"><span t-field="line.price"/></td>
                                    <td name="td_subtotal" class="text-right"><span t-field="line.subtotal"/></td>
                                </tr>
                            </t>
                        </tbody>
                    </table>
                    
                    <div class="row">
                        <div class="col-4 offset-8">
                            <table class="table table-sm">
                                <tr class="border-black">
                                    <td><strong>Total</strong></td>
                                    <td class="text-right">
                                        <span t-field="doc.total"/>
                                    </td>
                                </tr>
                            </table>
                        </div>
                    </div>
                    
                    <div class="oe_structure"/>
                </div>
            </t>
        </template>
        
        <template id="report_model_name">
            <t t-call="web.html_container">
                <t t-foreach="docs" t-as="doc">
                    <t t-call="model.name.report_model_name_document" t-lang="doc.partner_id.lang"/>
                </t>
            </t>
        </template>
    </data>
</odoo>

Security Group View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Custom Groups -->
        <record id="group_model_name_user" model="res.groups">
            <field name="name">Model Name User</field>
            <field name="category_id" ref="base.module_category_hidden"/>
            <field name="comment">Basic access to Model Name</field>
            <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
        </record>
        
        <record id="group_model_name_manager" model="res.groups">
            <field name="name">Model Name Manager</field>
            <field name="category_id" ref="base.module_category_hidden"/>
            <field name="comment">Full access to Model Name</field>
            <field name="implied_ids" eval="[(4, ref('group_model_name_user'))]"/>
        </record>
        
        <!-- Sample Users Data -->
        <record id="user_model_name_demo_user" model="res.users">
            <field name="name">Model Name Demo User</field>
            <field name="login">model_name_demo_user</field>
            <field name="groups_id" eval="[(4, ref('group_model_name_user'))]"/>
            <field name="password">model_name_demo_user</field>
            <field name="email">model_name_demo_user@example.com</field>
        </record>
    </data>
</odoo>

Security Rule View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Access Rights -->
        <record id="access_model_name_user" model="ir.model.access">
            <field name="name">model.name.user.access</field>
            <field name="model_id" ref="model_model_name"/>
            <field name="group_id" ref="group_model_name_user"/>
            <field name="perm_read" eval="1"/>
            <field name="perm_write" eval="1"/>
            <field name="perm_create" eval="1"/>
            <field name="perm_unlink" eval="0"/>
        </record>
        
        <record id="access_model_name_manager" model="ir.model.access">
            <field name="name">model.name.manager.access</field>
            <field name="model_id" ref="model_model_name"/>
            <field name="group_id" ref="group_model_name_manager"/>
            <field name="perm_read" eval="1"/>
            <field name="perm_write" eval="1"/>
            <field name="perm_create" eval="1"/>
            <field name="perm_unlink" eval="1"/>
        </record>
        
        <!-- Record Rules -->
        <record id="rule_model_name_user_own" model="ir.rule">
            <field name="name">model.name: Users access only their own records</field>
            <field name="model_id" ref="model_model_name"/>
            <field name="domain_force">[('create_uid', '=', user.id)]</field>
            <field name="groups" eval="[(4, ref('group_model_name_user'))]"/>
            <field name="perm_read" eval="1"/>
            <field name="perm_write" eval="1"/>
            <field name="perm_create" eval="1"/>
            <field name="perm_unlink" eval="0"/>
        </record>
        
        <record id="rule_model_name_manager_all" model="ir.rule">
            <field name="name">model.name: Managers access all records</field>
            <field name="model_id" ref="model_model_name"/>
            <field name="domain_force">[(1, '=', 1)]</field>
            <field name="groups" eval="[(4, ref('group_model_name_manager'))]"/>
            <field name="perm_read" eval="1"/>
            <field name="perm_write" eval="1"/>
            <field name="perm_create" eval="1"/>
            <field name="perm_unlink" eval="1"/>
        </record>
    </data>
</odoo>

Sequence View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
    <!-- Sequence -->
    <record id="seq_model_name" model="ir.sequence">
        <field name="name">Model Name Sequence</field>
        <field name="code">model.name</field>
        <field name="prefix">MOD/%(year)s/</field>
        <field name="padding">5</field>
        <field name="company_id" eval="False"/>
    </record>
</odoo>

Settings View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- Inherit Res Config Settings Form -->
        <record id="model_name_settings_view_form" model="ir.ui.view">
            <field name="name">model.name.settings.inherit.view</field>
            <field name="model">res.config.settings</field>
            <field name="inherit_id" ref="base.view_res_config_settings"/>
            <field name="arch" type="xml">
                <xpath expr="//div[@id='settings']" position="inside">
                    <div class="app_settings_block" data-string="Model Name Settings">
                        <h2>Model Name Settings</h2>
                        <group>
                            <field name="your_field_setting"/>
                            <!-- Add more fields if needed -->
                        </group>
                    </div>
                </xpath>
            </field>
        </record>
    </data>
</odoo>

Cron Job View

xml
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
    <!-- Scheduled Action -->
    <record id="ir_cron_model_name" model="ir.cron">
        <field name="name">Model Name Scheduler</field>
        <field name="model_id" ref="model_model_name"/>
        <field name="state">code</field>
        <field name="code">
            model.method_to_run()
        </field>
        <field name="interval_number">1</field>
        <field name="interval_type">days</field>
        <field name="numbercall">-1</field>
        <field name="active" eval="True"/>
    </record>
</odoo>

CSV Files

Security Access Rights (ir.model.access.csv)

csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_model_name_user,model.name.user,model_model_name,base.group_user,1,1,1,1

Best Practices

  1. Naming Conventions

    • Use lowercase with underscores for Python files
    • Use descriptive names for XML files
    • Follow Odoo's naming conventions
  2. File Organization

    • Keep related files together
    • Use appropriate subdirectories
    • Maintain module structure
  3. Template Selection

    • Choose the most appropriate template
    • Customize as needed
    • Remove unused code

Next Steps