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
- Right-click on the folder where you want the new file
- Select New → New Odoo File
- Choose the file type: Python, XML, or CSV
- Select the desired content template
- Name the file and press Enter
Supported File Types
Python Files
__init__.py
# -*- coding: utf-8 -*-
from . import models
from . import controllers
Basic initialization file with:
- Encoding declaration
- Import placeholders
__manifest__.py
# -*- 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,
}
Ready-to-edit manifest file with:
- Standard metadata
- Name, version, category
- Dependencies
- Data files
Odoo Model
# -*- coding: utf-8 -*-
from odoo import api, fields, models
class ModelName(models.Model):
""" This model represents model.name."""
_name = 'model.name'
_description = 'ModelName'
name = fields.Char(string='Customer Name', required=True)
active = fields.Boolean(default=True)
@api.model_create_multi
def create(self, vals):
"""Override the default create method to customize record creation logic."""
return super().create(vals)
Model definition file with:
- Required imports
- Sample model class
- Fields
- Basic
create
method
Odoo Controller
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
class MainController(http.Controller):
"""Controller class to handle HTTP routes."""
@http.route('/main', auth='public', website=True)
def index(self, **kw):
return request.render('your_module.template_id', {'sample_data': 'Sample Data'})
Controller file including:
- Required imports
- Controller class
- Sample
@http.route
methods - Web/API endpoints

XML Files
Empty XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Your custom views here -->
</odoo>
Blank XML file for:
- Custom configurations
- Advanced use cases
Basic View XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="model_name_view_form" model="ir.ui.view">
<field name="name">model.name.view.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_view_list" model="ir.ui.view">
<field name="name">model.name.view.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="model_name_action" 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="model_name_menu"
name="Model name"
action="model_name_action"
sequence="10"/>
</odoo>
Minimal view definitions:
- Form views
- Tree views
- Basic fields
- Standard attributes
Advanced View XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Form View -->
<record id="model_name_view_form" model="ir.ui.view">
<field name="name">model.name.view.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_view_list" model="ir.ui.view">
<field name="name">model.name.view.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_view_search" model="ir.ui.view">
<field name="name">model.name.view.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_view_calendar" model="ir.ui.view">
<field name="name">model.name.view.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_view_kanban" model="ir.ui.view">
<field name="name">model.name.view.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="model_name_action" 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_view_search"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create your first model name!
</p>
</field>
</record>
<!-- Menu -->
<menuitem id="model_name_menu"
name="Model name"
action="model_name_action"
sequence="10"/>
</odoo>
Complex views featuring:
- Groups
- Notebooks
- Status bars
- Rich UI layouts
Inherited View XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Inherit Form View -->
<record id="model_name_view_form" model="ir.ui.view">
<field name="name">model.name.view.form.inherit.module</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_view_list" model="ir.ui.view">
<field name="name">model.name.view.list.inherit.module</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>
</odoo>
Template for extending views:
<xpath>
usage- View inheritance
- Field modifications
Report XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Report Action -->
<record id="module_action_report" model="ir.actions.report">
<field name="name">Module Report</field>
<field name="model">module</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">module.report_module</field>
<field name="report_file">module.report_module</field>
<field name="binding_model_id" ref="model_module"/>
<field name="binding_type">report</field>
</record>
<!-- Report Template -->
<template id="report_module_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_module">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="module.report_module_document" t-lang="doc.partner_id.lang"/>
</t>
</t>
</template>
</odoo>
Printable report templates:
- PDF/HTML output
- Report actions
- QWeb templates
Security Group XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Custom Groups -->
<record id="module_name_group_user" model="res.groups">
<field name="name">Module name groups User</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="comment">Basic access to Module name groups</field>
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
</record>
<record id="module_name_group_manager" model="res.groups">
<field name="name">Module name groups Manager</field>
<field name="category_id" ref="base.module_category_hidden"/>
<field name="comment">Full access to Module name groups</field>
<field name="implied_ids" eval="[(4, ref('module_name_group_user'))]"/>
</record>
<!-- Sample Users Data -->
<record id="module_name_group_demo_user" model="res.users">
<field name="name">Module name groups Demo User</field>
<field name="login">module_name_groups_demo_user</field>
<field name="password">module_name_groups_demo_user</field>
<field name="email">module_name_groups_demo_user@example.com</field>
<field name="groups_id" eval="[(4, ref('module_name_group_user'))]"/>
</record>
</odoo>
Two access groups:
User
: Basic access groupManager
: Inherits permissions fromUser
- Hierarchical permissions using
implied_ids
- Demo user assigned to the
User
group
Security Rule XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Access Rights -->
<record id="access_model_name_user" model="ir.model.access">
<field name="name">model.name.user</field>
<field name="model_id" ref="model_model_name"/>
<field name="group_id" ref="model_name_group_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</field>
<field name="model_id" ref="model_model_name"/>
<field name="group_id" ref="model_name_group_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="model_name_rule_user" 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="perm_read" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="0"/>
<field name="groups" eval="[(4, ref('model_name_group_user'))]"/>
</record>
<record id="model_name_rule_manager" 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="perm_read" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_unlink" eval="1"/>
<field name="groups" eval="[(4, ref('model_name_group_manager'))]"/>
</record>
</odoo>
Two access groups:
User
: Can read, write, and create only their own records (unlink
disabled)Manager
: Full access to all records includingunlink
- Model-level access set via
ir.model.access
- Record-level domain-based filtering using
ir.rule
- Controlled visibility and permission enforcement for groups:
model_name_group_user
andmodel_name_group_manager
Sequence XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- Sequence -->
<record id="seq_ir_sequence_data" model="ir.sequence">
<field name="name">Ir sequence data Sequence</field>
<field name="code">ir.sequence.data</field>
<field name="prefix">IR_/%(year)s/</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
</data>
</odoo>
sequence data
records:
- code
- prefix
- padding
- company_id
Settings XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Inherit Res Config Settings Form -->
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.res_config_settings</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='settings']" position="inside">
<div class="app_settings_block" data-string="Res config settings Settings">
<h2>Res config settings Settings</h2>
<group>
<field name="your_field_setting"/>
<!-- Add more fields if needed -->
</group>
</div>
</xpath>
</field>
</record>
</odoo>
Custom settings templates:
- Config panels
- System parameters
- User preferences
Cron Job XML
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- Scheduled Action -->
<record id="ir_cron_ir_cron_data" model="ir.cron">
<field name="name">Ir cron data Scheduler</field>
<field name="model_id" ref="model_ir_cron_data"/>
<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>
</data>
</odoo>
Scheduled actions:
- Recurring jobs
- Methods
- Intervals
- Active states

Keyboard Shortcuts
Action Name | Default Shortcut | Mac OS X Shortcut |
---|---|---|
Open Odoo File Creation Menu | Alt + Shift + F | ⌘ + ⇧ + F |
Create Odoo Model File | Alt + Shift + D | ⌘ + ⇧ + D |
Create Odoo View File | Alt + Shift + V | ⌘ + ⇧ + V |
Create Odoo Access File | Alt + Shift + A | ⌘ + ⇧ + A |
You can customize or add your own keyboard shortcuts by following these steps:
- Open
Settings
(orPreferences
on macOS). - Navigate to
Keymap
in the left sidebar. - Expand the
Plugins
section. - Locate and expand
Cybrosys Assista: Odoo Helper
from the list. - Find the specific action you want to configure.
- Right-click on the action and choose Add
Keyboard Shortcut
. - Press your desired key combination and apply the changes.
Tip: You can also remove or reassign conflicting shortcuts from the same menu.

CSV Files
Security File
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_model_name_user,access.model.name.user,model_model_name,base.group_user,1,1,1,1
Access control rules:
- Model names
- Groups
- Permissions (read, write, create, delete)
Context-Aware File Creation
The File Creator includes intelligent context-aware features that ensure files are created in appropriate locations and follow Odoo module structure conventions. Additionally, it automatically manages file registration in your module's configuration files.
Automatic File Registration
When you create new files using the File Creator, the plugin automatically:
Python Files
- Models: Automatically adds model imports to
__init__.py
files - Controllers: Automatically adds controller imports to
__init__.py
files
XML Files
- Views: Automatically adds view files to the
data
key in__manifest__.py
Benefits of Automatic Registration
- No Manual Updates: Eliminates the need to manually update
__init__.py
and__manifest__.py
- Reduces Errors: Prevents missing imports and data file references
- Maintains Consistency: Ensures all files are properly registered
- Saves Time: Focus on development instead of configuration management
- Team Efficiency: Standardized file registration across development teams
Directory Validation
- Module Templates: Can only be created inside valid directories that follow Odoo module structure
- File Placement: Automatically detects and validates target directory context
- Structure Compliance: Ensures proper module organization from the start
Component-Specific Restrictions
Python File Creation
- Models Directory: Python model files can only be created in
models/
directories - Controllers Directory: Controller files restricted to
controllers/
directories

XML File Creation
- Views Directory: View files (form, list, search, kanban) restricted to
views/
directories

Benefits of Context-Aware Creation
- Prevents Errors: Eliminates creation of files in wrong locations
- Maintains Structure: Ensures consistent module organization
- Follows Standards: Enforces Odoo development conventions
- Reduces Confusion: Clear guidance on where files should be placed
- Team Consistency: Standardized file organization across development teams
Smart Validation Features
- Location Detection: Automatically identifies current directory context
- Template Filtering: Shows only relevant templates based on location
- Error Prevention: Prevents creation of incompatible file types in wrong directories
- Guidance: Provides clear feedback when attempting to create files in invalid locations
Best Practices
Naming Conventions
- Use lowercase with underscores for Python files
- Use descriptive names for XML files
- Follow Odoo's naming conventions
File Organization
- Keep related files together
- Use appropriate subdirectories
- Maintain module structure
Template Selection
- Choose the most appropriate template
- Customize as needed
- Remove unused code
Context Awareness
- Create files in the correct directories
- Follow the component-specific restrictions
- Leverage the smart validation features
Next Steps
- Learn about Module Templates for creating complete modules
- Explore Code Snippets for quick code generation
- Check out Best Practices for file organization