Skip to content
Home » Odoo Dynamic View Tutorial

Odoo Dynamic View Tutorial

  • Odoo
Odoo Dynamic View

Build Live SQL Views

First, Odoo Dynamic View allows developers to merge data from multiple Odoo models into a single real-time view. Next, this dynamic SQL view relies on PostgreSQL to deliver up-to-date information without redundancy. Then, we guide you through every step for creating and deploying an Odoo Dynamic View in your custom module. Moreover, you can optimize performance and maintain data integrity with this approach. Additionally, you can find more details in the official Odoo ORM documentation: https://www.odoo.com/documentation/15.0/developer/reference/addons/orm.html.

source : https://www.linkedin.com/posts/ali-el-mohammady-74670b282_odoo-erp-odoodevelopment-ugcPost-7307542861724422145-PtC9/?rcm=ACoAAAUPxrsB223ygjog-L-91vracbuFPIw07-c&utm_source=pocket_saves


Understanding Odoo Dynamic View Basics

First, we define what an Odoo Dynamic View is and why it matters. Next, we contrast it with a standard Odoo model that creates its own database table. Then, we show that Odoo Dynamic View uses the _auto = False flag to avoid table creation. Moreover, we explain that you implement the view in the model’s init() method using PostgreSQL’s CREATE OR REPLACE VIEW command. Additionally, we note that this approach keeps your data normalized and fresh, because PostgreSQL generates results on demand. Finally, we link to PostgreSQL’s CREATE VIEW docs for deeper reading: https://www.postgresql.org/docs/current/sql-createview.html.

What Is a Live SQL View?

First, a live SQL view acts like a virtual table that executes a SELECT query on demand. Next, it draws rows from one or more tables at query time. Then, it never stores data physically beyond its base tables. Moreover, it ensures that any change in the source tables appears instantly in the view. Additionally, it enforces data consistency across your reports without manual refresh.

Why Choose Odoo Dynamic View?

First, you avoid maintaining duplicate fields or tables. Next, you leverage PostgreSQL’s query planner for optimized joins. Then, you reduce module upgrade complexity by moving logic to SQL. Moreover, you enable advanced reporting by exposing computed fields in a tree or form view. Additionally, you combine data from diverse models without writing heavy Python loops.


Advantages of Odoo Dynamic View

First, Odoo Dynamic View delivers real-time data updates. Next, it prevents data duplication by pulling live records. Then, it reduces Python overhead because PostgreSQL handles joins and filters. Moreover, it improves performance for complex reports. Additionally, it offers a clean separation between data storage and presentation logic.

Real-Time Insights

First, you get immediate feedback when source records change. Next, you avoid stale caches or delayed cron jobs. Then, you display up-to-the-second KPIs in dashboards. Moreover, you maintain trust in your reports because they reflect the current database state.

Better Maintainability

First, you centralize logic in the SQL view definition. Next, you avoid scattered Python scripts that seed or migrate data. Then, you simplify future changes by editing one SQL query. Moreover, you reduce risk of mismatched updates across tables.


Prerequisites for Creating an Odoo Dynamic View

First, you install Odoo (v14+ recommended) and PostgreSQL. Next, you grant your Odoo user rights to create views in the database. Then, you ensure basic familiarity with Python, XML, and SQL. Moreover, you set up a custom module scaffold. Additionally, you verify that your module depends on any models you join in the view.

Environment Setup

First, you create a new addon folder under addons/. Next, you include an __init__.py and a __manifest__.py. Then, you install any required community modules. Moreover, you start your Odoo server in developer mode. Additionally, you open logs to spot SQL errors early.

Database Permissions

First, you confirm that the Odoo database user has CREATE and DROP privileges. Next, you test view creation manually in psql. Then, you note any permission failures and adjust roles. Moreover, you restart Odoo to pick up permission changes.


Module Structure for Odoo Dynamic View

First, we outline a typical file layout for a dynamic view module:

my_dynamic_view/
├── __init__.py
├── __manifest__.py
├── models/
│   ├── __init__.py
│   └── student_school_dynamic_view.py
└── views/
    └── student_school_dynamic_view_views.xml

Next, we explain each file’s role. Then, we point out that you place Python code under models/ and XML under views/. Moreover, we mention that you import your Python file in models/__init__.py. Additionally, we note that you reference the XML in the manifest under the data key.

init.py

First, your root __init__.py imports the models package. Next, you write:

# __init__.py
from . import models

models/init.py

First, you import your dynamic view file. Next, you write:

# models/__init__.py
from . import student_school_dynamic_view

manifest.py

First, you declare module metadata and dependencies. Next, you include your XML under data. Then, you ensure proper versioning. Moreover, you set installable: True. Additionally, you describe your module’s summary.

# __manifest__.py
{
    'name': 'Student School Dynamic View',
    'version': '1.0',
    'author': 'Your Name',
    'category': 'Education',
    'summary': 'Odoo Dynamic View for combined student-school data',
    'depends': ['base', 'school_management'],
    'data': [
        'views/student_school_dynamic_view_views.xml',
    ],
    'installable': True,
    'application': False,
}

Defining the Python Model for Odoo Dynamic View

First, we write the Python class that defines our dynamic view. Next, we set _auto = False to prevent table creation. Then, we implement an init() method that drops and recreates the SQL view. Moreover, we expose fields that map directly to the SQL query’s columns. Additionally, we include detailed comments to clarify each step.

student_school_dynamic_view.py

# models/student_school_dynamic_view.py
from odoo import models, fields, tools

class StudentSchoolDynamicView(models.Model):
    _name = 'student.school.dynamic.view'
    _description = 'Combined Student and School Data'
    _auto = False  # Skip table creation, use SQL view instead

    school_name  = fields.Char(string='School Name')
    school_phone = fields.Char(string='Phone')
    school_email = fields.Char(string='Email')
    school_type  = fields.Selection([
        ('private', 'Private School'),
        ('public',  'Public School'),
    ], string='Type')
    student_name = fields.Char(string='Student Name')
    student_rno  = fields.Char(string='Roll Number')
    student_fees = fields.Float(string='Fees')
    student_seq  = fields.Integer(string='Sequence')

    def init(self):
        """Create or replace the SQL view for dynamic data."""
        # Drop existing SQL view if present
        tools.drop_view_if_exists(self.env.cr, self._table)
        # Build the SQL query for the view
        query = f"""
            CREATE OR REPLACE VIEW {self._table} AS (
                SELECT
                    std.id               AS id,
                    std.roll_number      AS student_rno,
                    std.name             AS student_name,
                    std.student_fees     AS student_fees,
                    std.student_seq      AS student_seq,
                    sp.name              AS school_name,
                    sp.phone             AS school_phone,
                    sp.email             AS school_email,
                    sp.school_type       AS school_type
                FROM school_student AS std
                JOIN school_profile AS sp
                  ON std.school_st_id = sp.id
            )
        """
        # Execute the SQL to register the view
        self.env.cr.execute(query)

First, we import models, fields, and tools from Odoo. Next, we define the model and disable _auto. Then, we list each field to match SQL columns. Moreover, we implement init() that drops and recreates the view. Finally, we execute the SQL query via the database cursor.


Setting Up the XML View Definition

First, we expose our dynamic model in the UI via an XML tree view. Next, we reference the model name and list fields in the desired order. Then, we add a menu item and an action for easy access. Moreover, we ensure that users can search and filter on any field. Additionally, we include a record for the ir.ui.menu entry.

student_school_dynamic_view_views.xml

<!-- views/student_school_dynamic_view_views.xml -->
<odoo>
  <!-- Tree view for dynamic data -->
  <record id="view_student_school_dynamic_tree" model="ir.ui.view">
    <field name="name">student.school.dynamic.tree</field>
    <field name="model">student.school.dynamic.view</field>
    <field name="arch" type="xml">
      <tree string="Student & School Data">
        <field name="student_seq"/>
        <field name="school_name"/>
        <field name="school_phone"/>
        <field name="school_email"/>
        <field name="school_type"/>
        <field name="student_name"/>
        <field name="student_rno"/>
        <field name="student_fees"/>
      </tree>
    </field>
  </record>

  <!-- Action to open the tree view -->
  <record id="action_student_school_dynamic" model="ir.actions.act_window">
    <field name="name">Student-School Report</field>
    <field name="res_model">student.school.dynamic.view</field>
    <field name="view_mode">tree</field>
  </record>

  <!-- Menu item under Reporting -->
  <menuitem id="menu_student_school_dynamic"
            name="Student-School Report"
            parent="school_management.menu_reporting"
            action="action_student_school_dynamic"/>
</odoo>

First, we define the tree view with all fields. Next, we create an action to launch the view. Then, we add a menu entry under the existing reporting menu. Moreover, we ensure string labels read clearly. Finally, we validate the XML with Odoo’s schema.


Configuring the Manifest for Odoo Dynamic View

First, we update __manifest__.py to include our XML. Next, we declare dependencies on modules that supply base models (e.g., school_management). Then, we list views/student_school_dynamic_view_views.xml under data. Moreover, we set installable to True. Additionally, we provide a concise summary and description for SEO.

# __manifest__.py
{
    'name': 'Student School Dynamic View',
    'version': '1.0',
    'summary': 'Odoo Dynamic View for combined student and school data',
    'description': 'This module creates an Odoo Dynamic View that combines student and school info into a live SQL view.',
    'author': 'Your Name',
    'category': 'Education',
    'depends': ['base', 'school_management'],
    'data': [
        'views/student_school_dynamic_view_views.xml',
    ],
    'installable': True,
    'application': False,
}

First, we include the view XML under data. Next, we confirm the dependency modules. Then, we save changes and restart Odoo. Moreover, we install the module via Apps. Finally, we verify that the dynamic view appears in the menu.


Testing Your Odoo Dynamic View

First, we perform manual tests to confirm that the view shows correct data. Next, we navigate to the “Student-School Report” menu. Then, we verify that all fields display and match underlying tables. Moreover, we create new school_profile and school_student records to test real-time updates. Additionally, we ensure that filters and sorting work as expected.

Automated Test with TransactionCase

First, we write a Python test to install the module and check the view. Next, we create test records and run a SELECT query on the SQL view. Then, we assert that the view returns the expected number of rows. Moreover, we incorporate this test into our CI pipeline.

# tests/test_dynamic_view.py
from odoo.tests.common import TransactionCase
from odoo import tools

class TestStudentSchoolDynamicView(TransactionCase):
    def setUp(self):
        super().setUp()
        self.school = self.env['school_profile'].create({
            'name': 'Test School',
            'phone': '1234567890',
            'email': 'info@test.edu',
            'school_type': 'public',
        })
        self.student = self.env['school_student'].create({
            'name': 'Test Student',
            'roll_number': 'R001',
            'student_fees': 100.0,
            'student_seq': 1,
            'school_st_id': self.school.id,
        })

    def test_view_content(self):
        result = self.env.cr.execute(f"SELECT * FROM {self.env['student.school.dynamic.view']._table}")
        rows = self.env.cr.fetchall()
        assert len(rows) == 1
        assert rows[0][2] == 'Test Student'

First, we import TransactionCase and tools. Next, we create a school and student record. Then, we query the SQL view directly. Moreover, we assert correct row count and content. Finally, we run tests with:

# run pytest for automated validation
$ pytest --maxfail=1 --disable-warnings -q

Troubleshooting Odoo Dynamic View Errors

First, we identify common SQL syntax mistakes. Next, we check that table names match the database schema. Then, we verify that the view’s id column aligns with model requirements. Moreover, we inspect Odoo logs for cursor errors like “relation does not exist.” Additionally, we open a psql shell to test the view query manually.

Common Error: Missing Column

First, an “undefined column” error occurs when you rename a field. Next, you update your SQL query to include the new column name. Then, you drop and recreate the view with the adjusted init() method. Moreover, you restart Odoo to refresh the cache.

Common Error: Permission Denied

First, you get “permission denied for relation…” when your DB user lacks privileges. Next, you grant SELECT on underlying tables:

GRANT SELECT ON school_profile TO odoo;
GRANT SELECT ON school_student TO odoo;

Then, you rerun the module install. Moreover, you confirm that Odoo can now drop and create views.


Best Practices for Odoo Dynamic View

First, keep your SQL queries simple to aid readability. Next, avoid heavy computations in the view; offload them to reports or cron jobs. Then, document your SQL logic with comments inside the init() method. Moreover, version your view by tracking changes in your module’s changelog. Additionally, test your view on large datasets to catch performance issues early.

Performance Tips

First, index joined columns in underlying tables. Next, limit the view to necessary records using WHERE clauses. Then, use materialized views for extremely large datasets with periodic refresh. Moreover, choose read-only access when appropriate.

Security Tips

First, abide by Odoo’s record rules; avoid exposing sensitive fields. Next, use ir.rule definitions to restrict dynamic view records. Then, do not embed user input directly into SQL; use parameterized queries when needed.


Advanced Topics for Odoo Dynamic View

First, you can create parameterized dynamic views that accept filters via context or fields. Next, you can combine dynamic views with scheduled actions to prepopulate materialized views. Then, you can extend the view at runtime by registering new SQL snippets in other modules. Moreover, you can integrate dynamic views with BI tools by exposing them as read-only models. Additionally, you can publish Odoo Dynamic Views via REST APIs for external dashboards.


Conclusion

First, we covered how to build an Odoo Dynamic View by defining a Python model with _auto = False and an init() hook. Next, we exposed the view via XML, updated the manifest, and tested manually and automatically. Then, we discussed troubleshooting, best practices, and advanced uses. Moreover, you now understand how to deliver real-time, normalized reports without data duplication. Finally, you can apply this pattern to any Odoo module to enhance reporting and performance.


Discover more from teguhteja.id

Subscribe to get the latest posts sent to your email.

Leave a Reply

WP Twitter Auto Publish Powered By : XYZScripts.com