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 & Templates
Python Files
Template | Description |
---|---|
__init__.py | Basic initialization file with encoding and import placeholders |
__manifest__.py | Module manifest with metadata and dependencies |
Odoo Model | Model definition with fields and methods |
Odoo Controller | HTTP controller with routes and endpoints |
XML Files
Template | Description |
---|---|
Empty View | Blank XML file for custom configurations |
Basic View | Minimal form and list view definitions |
Advanced View | Complex views with groups, notebooks, and statusbars |
Inherit View | View inheritance and extension using xpath |
Report View | QWeb report templates and actions |
Security Group View | User groups and access rights |
Security Rule View | Record-level access control rules |
Sequence View | Sequence definition for automatic numbering |
Settings View | Settings form definition for configuration |
Cron Job View | Scheduled action definition for automation |
CSV Files
Template | Description |
---|---|
Security Access | Model 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
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
Next Steps
- Learn about Module Templates for creating complete modules
- Explore Code Snippets for quick code generation
- Check out Best Practices for file organization