Skip to Content

12 - Transient Models (models.TransientModel) and Wizards

Welcome back! So far, we have been building regular models using models.Model. Every time a user types data into those models and clicks save, that data lives in the PostgreSQL database forever.

But what if you don't want the data to live forever?

Imagine a user wants to print a specific report between two dates, or they want to select 50 books and apply a 20% discount to all of them at once. They need a pop-up window to enter this temporary information. Once they click "Confirm," the system does the math, and the temporary data should disappear.

In Odoo, we build these temporary pop-up windows using Wizards and Transient Models.


1. What is a Transient Model?

A Transient Model is built exactly like a regular model, but it inherits from models.TransientModel instead of models.Model.

When you use a Transient Model, Odoo still creates a table in PostgreSQL. However, Odoo has a background garbage-collection job that automatically deletes old records from this table every day. It keeps your database clean and prevents it from filling up with useless pop-up window data.


2. Creating the Wizard Model (Python)

Let's build a Wizard for our Library module. We want a pop-up window that asks the user for a "New Price", and when they click "Apply," it updates the prices of all the books they had selected in the list view.

Create a new Python file (e.g., wizard/update_price_wizard.py):

from odoo import models, fields, api

class UpdatePriceWizard(models.TransientModel):
# Notice we use TransientModel here!
_name = 'library.update.price.wizard'
_description = 'Mass Update Book Prices'

new_price = fields.Float(string='New Price', required=True)

def action_apply_price(self):
# 1. Get the IDs of the books the user selected before opening the wizard
active_ids = self.env.context.get('active_ids', [])
# 2. Fetch those specific books from the database
books = self.env['library.book'].browse(active_ids)
# 3. Update their prices
for book in books:
book.write({'price': self.new_price})
# 4. Tell the pop-up window to close automatically
return {'type': 'ir.actions.act_window_close'}


3. Creating the Wizard Form (XML)

Now we need to build the user interface for our pop-up. Wizard views look just like normal form views, but they have a special <footer> section at the bottom for the buttons.

<odoo>
<record id="view_update_price_wizard_form" model="ir.ui.view">
<field name="name">library.update.price.wizard.form</field>
<field name="model">library.update.price.wizard</field>
<field name="arch" type="xml">
<form string="Update Prices">
<sheet>
<group>
<field name="new_price" widget="monetary"/>
</group>
</sheet>
<footer>
<button name="action_apply_price" string="Apply Price" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-secondary" special="cancel"/>
</footer>
</form>
</field>
</record>
</odoo>



4. Launching the Wizard (The Action)

How do we actually open this pop-up? We create a Window Action, just like we do for regular menu items. But we add a magic ingredient: target="new".

<record id="action_update_price_wizard" model="ir.actions.act_window">
<field name="name">Update Book Prices</field>
<field name="res_model">library.update.price.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="binding_model_id" ref="model_library_book"/>
<field name="binding_view_types">list</field>
</record>

(By adding binding_model_id, Odoo automatically adds this wizard to the "Action" dropdown menu at the top of the Library Book list view!)


5. Pro-Tips & Advice

💡 PRO TIP: Don't Forget Security! Just because a model is temporary doesn't mean it bypasses security. You must add your library.update.price.wizard to your ir.model.access.csv file, exactly like you would for a normal model. If you don't, users will get an Access Error when they try to open the pop-up.

  • The Power of the Context: In the Python code above, we used self.env.context.get('active_ids'). The context is a temporary dictionary that Odoo passes around the screen. When a user checks the boxes next to 5 books in a list view and clicks an Action, Odoo secretly packs the IDs of those 5 books into the context under the key active_ids. This is how wizards know what records they are supposed to act upon!

  • Default Values in Wizards: You can use the default_get method to pre-fill the wizard's fields before the screen even loads. For example, you could calculate the average price of the selected books and put it in the new_price field automatically.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.