I was googling a lot and there are many people who ask this same question in Odoo forums, but nobody gives them an answer.
Finally, I found this workaround, which in my case worked perfectly: the method field_view_get
, which is in every single model, gets the XML view just before returning it to be shown. This means that you can manipulate the view from Python code in whatever way you want.
You only must know how to use a library like lxml
to modify the string variable with the XML code. I put my example:
RES.PARTNER model (Here we must use etree
from lxml
library)
@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False,
submenu=False):
res = super(res_partner, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
checking_obj = self.env['my.own.checkings']
doc = etree.XML(res['arch'])
if checking_obj.belongs_to_accountant_group():
doc.set('create', 'false')
doc.set('delete', 'false')
doc.set('edit', 'true')
if view_type == 'form':
accounting_pages = doc.xpath("//page[@name='accounting']")
accounting_page = accounting_pages[0] if accounting_pages \
else False
if accounting_page is not False:
if checking_obj.belongs_to_accountant_group():
all_fields = doc.xpath("//field")
for field in all_fields:
if accounting_page not in field.iterancestors():
checking_obj.set_modifiers(field,
{'readonly': True, })
res['arch'] = etree.tostring(doc)
return res
AUXILIAR CUSTOMIZED model (named MY.OWN.CHECKINGS) (Here we must use json
library)
def update_json_data(self, json_data=False, update_data={}):
''' It updates JSON data. It gets JSON data, converts it to a Python
dictionary, updates this, and converts the dictionary to JSON data
again. '''
dict_data = json.loads(json_data) if json_data else {}
dict_data.update(update_data)
return json.dumps(dict_data, ensure_ascii=False)
def set_modifiers(self, element=False, modifiers_upd={}):
''' It updates the JSON modifiers with the specified data to indicate
if a XML tag is readonly or invisible or not. '''
if element is not False: # Do not write only if element:
modifiers = element.get('modifiers') or {}
modifiers_json = self.update_json_data(
modifiers, modifiers_upd)
element.set('modifiers', modifiers_json)
def is_accountant(self):
return self.env.ref(
'my_module.group_accountant').id in \
self.env.user.groups_id.mapped('id')
This way you can make readonly some fields depending on the group of the current user.