Passing parameters to forms and actions: Context

Internally, every method in Odoo has access to a dictionary called context that is propagated from every action to the methods involved in delivering that action. The UI also has access to it and can be modified in various ways by setting values in the context. In this recipe, we'll explore some of the applications of this mechanism by toying with the language, default values, and implicit filters.

Getting ready

While not strictly necessary, this recipe will be more fun if you install the French language, in case you didn't start out with this language in the first place. Consult Chapter 11, Internationalization, for how to do this. If you have a French database, change fr_FR to some other language; en_US will do for English. Also, click the button Not archived on one of your customers in order to archive it and verify that this partner doesn't show up any more in the list.

How to do it...

  1. Create a new action, very similar to the one from the first recipe:
    <act_window id="action_all_customers_fr"
                name="Tous les clients"
                res_model="res.partner"
                domain="[('customer', '=', True)]"
                context="{'lang': 'fr_FR', 'default_lang': 'fr_FR', 
                    'active_test': False}" />
    
  2. Add a menu that calls this action. This is left as an exercise for the reader.

When you open this menu, the views will show up in French, and if you create a new partner, she will have French as the preselected language. A less obvious difference is that you will also see the partner you deactivated earlier.

How it works...

The context dictionary is populated from several sources. First, some values from the current user's record (lang and tz, for the user's language and the user's timezone) are read, then there are addons that add keys for their own purposes. Further, the UI adds keys about which model and which record we're busy with at the moment (active_id, active_ids, active_model). And as seen previously, we can also add our own keys in actions. Those are merged together and passed to the underlying server functions, and also to the client side UI.

So by setting the lang context key, we force the display language to be French. You will note that this doesn't change the whole UI language, which is because only the list view that we open lies within the scope of this context. The rest of the UI was loaded already with another context that contained the user's original language. But if you open a record in this list view, it will be presented in French too, and if you open some linked record on the form or press a button that executes an action, the language will be propagated too.

By setting default_lang, we set a default value for every record created within the scope of this context. The general pattern is default_$fieldname: my_default_value, which enables you to set default values for the partners newly created in this case. Given that our menu is about customers, it might have made sense to also set default_customer: True to have the Customer field checked by default. But this is a model wide default for res.partner anyway, so this wouldn't have changed anything. For scalar fields, the syntax for this is as you would write it in Python code – string fields go in quotes, numbers just like that, and boolean fields are either True or False. For relational fields, the syntax is slightly more complicated – refer to Chapter 9, Module Data, for how to write those. Note that the default values set in the context override the default values set in the model definition, so you can have different default values in different situations.

The last key is active_test, which has very special semantics. For every model that has a field called active, Odoo automatically filters out the records where this field is False. This is why the partner where you unchecked this field disappeared from the list. By setting this key, we can suppress this behavior.

Note

This is useful for the UI in its own right, but even more useful in your Python code when you need to be sure some operation is applied to all the records, not just the active ones.

There's more...

While defining a context you have access to some variables, the most important one being uid, which evaluates to the current user's ID. You'll need this for setting the default filters (see the next recipe). Further, you have access to the function context_today and the variable current_date, where the first is a date object representing the current date as seen from the user's time zone and the latter the current date as seen in UTC, formatted as YYYY-MM-DD. For setting a default for a date field to the current date by default, use current_date and, for default filters, use context_today().

Further, you can do some date calculations with a subset of Python's datetime, time, and relativedelta classes.

Tip

Why the repeated talk about 'a subset of Python'? For various technical reasons, domains have to be evaluated as well on the client side as on the server side. Server side evaluation existed earlier, there full Python was available (but is restricted by now too for security reasons). When client side evaluation was introduced, the best option in order not to break the whole system was to implement a part of Python in JavaScript. So there is a small JavaScript Python interpreter built into Odoo which works great for simple expressions, and that is usually enough.

Beware about variables in the context in conjunction with the <act_window /> shortcut. Those are evaluated at installation time, which is nearly never what you want. If you need variables in your context, use <record /> syntax.

The same way that we added some context keys in our action, we can do with buttons. This causes the function or action the button calls to be run in the context given and by now you know some of the tricks you can pull this way.

Most form element attributes that are evaluated as Python also have access to the context dictionary. The attributes invisible and readonly are such attributes. So in cases where you want an element to show up in a form sometimes, but not at other times, you set the invisible attribute to context.get('my_key'), and for actions that lead to the case where the field is supposed to be invisible, you set the context key my_key: True. Such a strategy enables you to adapt your form without having to rewrite it for different occasions.

You can also set a context on relational fields, which influences how the field is loaded. By setting the keys form_view_ref or tree_view_ref to the XML ID of a view, you can select a specific view for this field. This is necessary when you have multiple views of the same type for the same object. Without this key you get the view with the lowest sequence number, which might not always be desirable.

See also

One of the very useful applications of the context is to set default search filters as described in the recipe Search views.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset