How to Empty a Model In Odoo / Mass Delete in Odoo / Mass Unlink

In Odoo, we use unlink() ORM method to delete a record. But if you are trying to empty a model or wants to delete multiple records, the best way to do it, is to use two steps.

First, search the records:

record_set = self.env['your.model'].search([])

Second, unlink them all at once instead of looping through them:

record_set.unlink()

If you have a list of ids, search them using the list:

ids = [1, 2, 3, 10, 11, 12]
record_set = self.env['your.model'].search([('id', 'in', ids)])

and unlink:

record_set.unlink()

Remember, there is no need to loop through this iterable object, odoo unlink does it for you.

TIPS: If you want to get all the ids in a model directly in a list, you can use the following:

record_list = self.env['your.model'].search([]).ids

How to Hide a Column Dynamically in a Parent Model in Tree View on Odoo

We all know how to hide a column in a model based on parent value matching in Odoo installation. I have already written a post on this here:

How to hide a column ‘dynamically’ in Tree View on Odoo

Above case works when you are trying a hide a column in a sale order line, or move line or invoice line. But what if, you want to hide a column in stock picking delivery tree view or the receipt view? The above method, will not work, because column_invisible only works when the parent is referenced. But in a tree view list like ‘Deliver Orders’ under Inventory Overview, if you want to hide a column based on condition, how do we do that?

The answer is, we use data from context and set the attribute ‘invisible’ to True based on the context value. We can either do that by using any existing context value or we can add a context value using a computed field property and match it in the xml.

I will discuss on how can we use the existing context key:value pair in hiding a column on stock.picking model.

First, let’s imagine, we have a character field on stock.picking called ‘woocommerce_id’.

class stock_picking(models.Model):
_inhert = 'stock.picking'

woocommerce_id = fields.Char(string="Woocommerce ID")

Now the xml for Inventory overview stock.picking trees would be inheriting stock.vpicktree

<record id="inherit_delivery_picking" model="ir.ui.view">
<field name="name">stock.picking.inherit.delivery.picking</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='location_dest_id']" position="after">
<field name="woocommerce_id"/>
</xpath>
</field>
</record>

Now, the above will show woocommerce_id in all vpicktree view, like ‘Delivery Orders’, ‘Receipts’, ‘Internal Transfers’. But What if, you want to show this field to only Delivery Orders?

To do that, we need to know the value for ‘default_picking_type_id’. This value is automatically set on stock.picking model view in the context by Odoo (Hints: You may view all the keys available to context in a model, by creating a computed field, that writes self.env.context.keys() to a file or show it in the tree view to find the keys, and self.env.context.get(‘key_name’) to find the value for it).

If you check the different values set by that key for different pages, you can see, it is set to 1 for delivery orders, 3 for receipts and 5 for internal transfers. Now if you want to show the woocommerce_id field to only delivery receipts, we set the attribute invisible for that field when the context key value is not 1 like following:

<field name="woocommerce_id" invisible="context.get('default_picking_type_id') != 1"/>

Save it, upgrade the module, and see the magic! cheers!

How to Update Context in Odoo

You may want to pass some data to a specific page in Odoo, and change the fields based on those data. In those cases, you want to use Context. Context is a data structure passed to the request object that contains hidden values, and can be used to change results of the page.

Context is a frozendict data type in Odoo. That’s why you can change it like you do in a dict data type, for example:

dict_object.update({
'test': 'test_value',
})

As the Context is frozendict, it won’t take such changes. Odoo provides a way to change values, it’s called ‘with_context’. The syntax is as following:

self = self.with_context({
'test': 'test_value',
})

This one should rewrite the context available in the self object by adding the new key:value pair you have mentioned. There are times, this might not work as expected, and you want a patch technique to update the context. This can be done by changing the data type to dict.

self.env.context = dict(self.env.context)
self.env.context.update({
'test': 'test_value',
})

This would also add the new key:value pair to your context and work as expected. There is almost no security concern here for converting the frozendict as the context will destroy once the page is left soon enough.