How to Use Odoo’s Context Like a Pro

Context in odoo ecosystem is a python dictionary which is usually used as a marker to turn a feature off or on. With a context we can set a model to have different features if opened from different menus. For example, let’s say we have a master product like the picture below.

Odoo master product with internal reference

Pay attention to the Internal Reference field on the master product above. If we make a Sales Quotation, the Internal Reference will be displayed next to the product name. As shown below.

Odoo sales order with a product and its internal reference

Product’s Internal Reference on the view can be configured to appear or not by using a context. Please take a look at this snippet from odoo’s source code.

def name_get(self):
    # TDE: this could be cleaned a bit I think

    def _name_get(d):
        name = d.get('name', '')
        code = self._context.get('display_default_code', True) and d.get('default_code', False) or False
        if code:
            name = '[%s] %s' % (code,name)
        return (d['id'], name)

The code above is located in the product module, precisely in the /product/models/product.py file. From the code above, it can be seen that if the display_default_code context is True or does not exist, and the default_code has a value, then the Internal Reference (default_code) will be added beside the product name. Now let’s test the use of the display_default_code context.

First, as Administrator enter to debug mode. Open a Sales Quotation form. On the navbar, look for the insect icon, click it, then find the Edit Action menu. In the Context Value field, add the display_default_code context with the value of False. As shown below.

Edit odoo's sales quotation action

Context is written in Python Dictionary format, which is similar to JSON, so make sure it is written correctly. Click Save button then refresh the browser. Internal Reference should no longer be displayed, as shown below.

Odoo sales order with a product without its internal reference

Because the display_default_code context is only added to the Sales Quotation action, when we open the Sales Order or Purchase Order form, the Internal Reference will still appear.

The display_default_code context above is a specific context, it’s mean that it can be used to set up the display of the master product only. Odoo also has some general contexts that can be used for all models. This is some example of how to use general contexts which can be applied to all models.

Set the default value of a field

For example, assume we have a customer with id of 12. By using a context we can set up that when we press the Create button on the Sales Quotation, the customer field will automatically be filled with the customer’s name that have the id of 12.

This is how to do it, still in debug mode, click the button with the insect icon that located in navbar, then click the Edit Action menu. Then add a context with the format of default_ followed by the field name, like partner_id. Then followed by your desired default value like picture below.

Add default customer on sales quotation form

In my database, the customer that have id of 12 is Ready Mat.

odoo's master customer

So when i Click the Create button on Sales Quotation form, the Customer field will filled with Ready Mat automatically.

Odoo's sales quotation with customer filled automatically

Set the default filter of list view

With a context we can also set the default filter when we open the list view. To see the list of filters that available in the current list view action, on the insect icon click the Edit Control Panel View menu if you use odoo 13 or above, or click the Edit Search View menu if you use odoo below 13, then search for xml code with the filter tag.

Odoo's sales quotation control panel

Select one of the filters that you want to be automatically activated when we open the list view, for example the filter_create_date filter.

Then in the Edit Action menu, add a context with the format of search_default_ followed by the name of the filter. Then give the value of 1 or True. Like picture below.

Edit sales quotation filter in odoo

When you open the sales quotation list view, the filter_create_date filter will automatically be activated, as shown below.

Sales quotation in odoo with active filter

Set the default view

If a model has more than one views like in the res.partner model as shown below

Odoo's res.partner view list

We can control which views will be displayed by adding a form_view_ref or tree_view_ref context, depending on the type of view you want, followed by the external id of the view that you want to use, like the code below.

<field name="partner_id" context="{'form_view_ref': 'base.view_partner_short_form'}" />

When we click on the partner_id field, the base.view_partner_short_form form will be displayed. If we don’t manage the view via a context, the view with a smaller sequence will be displayed.

To see a list of views that a model has, still in debug mode, go to the Settings >> Technical >> User Interface >> Views menu. Then do a filter based on the model name and display type as shown on the imbage above. Click on a view to see the detailed information, including the External ID and its Sequence.

This is the image of the master customer when we click the Customer field in the Sales Quotation form, before we give a context like the code above.

Partner view in odoo's sales quotation

Meanwhile, the image below is the image after we give a context.

Simple partner view in odoo's sales quotation

Context can also be used in python. To get the context brought from the user interface or other methods we can use the code like below.

current_context = self._context
print(current_context)

Since context is a python dictionary, we can check whether our expected context exist or not with the code like below.

if 'my_context' in self._context:
	do_something()

Or if we want to be safer, we can use the default value like below.

if self._context.get('my_context', False):
	do_something()

With the code above, if the context that we expect doesn’t exist, it will return False. Otherwise it will return the actual value.

Context is frozen dictionary so we can’t directly add new context. The code below will cause an error.

self._context['my_context'] = 'test'

So we need to save the context in a temporary variable first, then we can add a new context. Like the code below.

current_context = dict(self._context)
current_context['my_context'] = 'test'

Then call the with_context method after the model name or record followed by the actual method. Like the code below.

current_context = dict(self._context)
current_context['my_context'] = 'test'

self.env['res.partner'].with_context(current_context).do_something(self.order.id)

Furthermore, in the related model and method, we can write our logic according to the context carried by the do_something method above.

class ResPartner(models.Model)
	_inherit = 'res.partner'

	def do_something(self, order_id):
		if self._context.get('my_context','test') == 'test':
			self.do_test(order_id)
		else:
			self.do_prod(order_id)

Please note, when we call the with_context method from the super method, the with_context method must be called after the model or the record, in this case the self variable. The code like below will cause an error.

def write(self, vals):
	current_context = dict(self._context)
	current_context['my_context'] = 'test'

	return super(SaleOrder, self).with_context(current_context).write(vals)

It should be like this.

def write(self, vals):
	current_context = dict(self._context)
	current_context['my_context'] = 'test'

	return super(SaleOrder, self.with_context(current_context)).write(vals)

Context is only used as a marker. Its real use needs to be adjusted according to your odoo application.

Related Article

Leave a Reply