* Environment.ref(xml_id, raise_if_not_found=True) - It will return the record corresponding to the xml_id.
* Environment.lang - It will return the current language code. Its return type: str.
* Environment.user - This returns the currently logged-in user (as an instance of the environment). The return type is res_users.
* Environment.company - This returns the currently active company (as an instance of the environment). If it is not specified in the context of instance (allowed_company_ids), then what it will do is that it returns the currently logged-in user's main company as the current active company. The return type of this is res.company, also if it is in sudo mode, a logged-in user can access any company, even if the user is not allowed in that company. It raises Access Error on invalid or unauthorized allowed_company_ids context key content.
* Environment.companies - This returns a recordset of all the companies enabled to the user. If it is not specified in the context of instance (allowed_company_ids), then what it will do is that it returns the currently logged-in user's main company as the currently active company. And also it will raise an Access Error for the invalid or an unauthorized allowed_company_ids as context key of the content.
Altering the Environment
* Model.with_context( [context] [, **overrides] ) -
The current recordset in a new version will be returned to you which will be attached to the instance extended context. The extended context will either provide the “context” in which the overrides are merged to or it will provide the “current context” in which overrides are merged.
Example -
# current context is {'key1': True}
r2 = records.with_context({}, key2=True)
# -> r2._context is {'key2': True}
r2 = records.with_context(key2=True)
# -> r2._context is {'key1': True, 'key2': True}
* Model.with_user(user) - The recordset in a new version will be returned with the respective used assigned as a non-super user, unless the given user is the superuser.
Example - self.env['res.config.settings'].with_user(self.user.id), It will return a new version of the current record set with the current user id.
* Model.with_company(res_company) - Consider the case that a user has logged in to two companies RED and GREEN with RED as the main company and he needs to create a record for the second company GREEN, the values for the company-dependent fields will be that of company RED.
To get the dependent fields set values of a company from another company, we need to ensure that the current company we are using is correct. This can be done with the help of with_company(), this will update the current company value.
Example-
val=record.with_company(company_GREEN).company_dependent_field
* Model.with_env(env) - This returns a new version recordset currently attached to the provided environment.
Example-
Actions = self. with_context(active_test=True).
sudo() .search(domain)
return actions.with_env(self.env)
* Model.sudo([flag=True]) - This returns a new version recordset with enabled or disabled superuser mode, depending on the value of the flag. Furthermore, the superuser mode which has been defined bypasses and overcomes the access rights checks without any hurdles as it is provided with the ultimate operations capability and does not change the current login user.
Example -
self.env['mail.mail'].sudo().create(mail_values)
The thing to keep in mind is that sudo will allow data access out of the boundaries of record rules set for a model, thereby the record which should be kept isolated will be mixed up, for example in a multi-company environment, data of different companies should not be mixed up.
SQL Execution
The ‘cr’ in the Odoo ORM environment stands for ‘cursor', which is used for transactions of the current database. Moreover, it also allows the execution of SQL queries directly in the database, either for queries that are difficult to express using the ORM (e.g. complex joins) or for performance reasons.
self.env.cr.execute("some_sql", params)
It is necessary to invalidate and clear cache when using SQL commands to CREATE, UPDATE or DELETE this is because the model uses the same cursor but the environment holds different caches.
Moreover, it can be performed using the invalidate_cache() method.
* Model.invalidate_cache(fnames=None, ids=None) - It is used to Invalidate the record caches after some modifications have been done to some records that are currently in cache. The whole cache will be cleared if both fnames and ids are None.
fnames – the list of modified fields, or None for all fields.
ids – the list of modified record ids or None for all
Example -
self.env['account.move.line'].invalidate_cache()
We can either use queries or ORM utilities, one thing we have to make sure is that when using queries, your queries are free of errors and bugs when using user input. Instead, it is recommended to use ORM utilities. This is because the security rules of Odoo and ORM may be bypassed when executing raw SQL queries.