Přejít na obsah
Menu
You need to be registered to interact with the community.
This question has been flagged
2 Odpovědi
386 Zobrazení

Hello,

I'm overriding the _get_view method to dynamically modify form views based on a custom context key mi_gestion. Here's a simplified version of my method:

@api.model

def _get_view(self, view_id=None, view_type='form', **options):

    arch, view = super()._get_view(view_id=view_id, view_type=view_type, **options)

    

    if view_type == 'form' and self._context.get('mi_gestion'):

        m2o_fields = [name for name, field in self._fields.items() if field.type == 'many2one']

        if m2o_fields:

            xpath_query = " | ".join(f".//field[@name='{name}']" for name in m2o_fields)

            nodes = arch.xpath(xpath_query)

            self._modify_m2o_field_option(nodes)

    

    return arch, view


The issue is that self._context.get('mi_gestion') always returns False, even though I'm passing mi_gestion=True via the frontend context.

  • Why is self._context not reflecting the custom context in _get_view?
  • Is there a better or more reliable approach to pass and access custom context values inside _get_view? 

Any help or insights would be appreciated!

Thanks in advance.

Avatar
Zrušit
Nejlepší odpověď

Hi,


Try the following code.


@api.model

def _get_view(self, view_id=None, view_type='form', **options):

    arch, view = super()._get_view(view_id=view_id, view_type=view_type, **options)


    # Get frontend context from options if available

    ctx = options.get('context') or self._context


    if view_type == 'form' and ctx.get('mi_gestion'):

        m2o_fields = [name for name, field in self._fields.items() if field.type == 'many2one']

        if m2o_fields:

            xpath_query = " | ".join(f".//field[@name='{name}']" for name in m2o_fields)

            nodes = arch.xpath(xpath_query)

            self._modify_m2o_field_option(nodes)


    return arch, view



Alternate method.

* Use fields_view_get instead of _get_view

        -Most customizations of views in Odoo are done by overriding fields_view_get.

                - This method always has access to the full context (frontend’s context is propagated properly).

Example:


@api.model

def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):

    res = super().fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)


    if view_type == 'form' and self._context.get('mi_gestion'):

        doc = etree.XML(res['arch'])

        m2o_fields = [name for name, field in self._fields.items() if field.type == 'many2one']

        if m2o_fields:

            xpath_query = " | ".join(f".//field[@name='{name}']" for name in m2o_fields)

            nodes = doc.xpath(xpath_query)

            self._modify_m2o_field_option(nodes)

            res['arch'] = etree.tostring(doc, encoding='unicode')


    return res


This is more standard and reliable than _get_view.



Hope it helps.

Avatar
Zrušit
Nejlepší odpověď

Hii,

Fix your code like this:

@api.model def _get_view(self, view_id=None, view_type='form', **options): arch, view = super()._get_view(view_id=view_id, view_type=view_type, **options) context = options.get('context') or {} if view_type == 'form' and context.get('mi_gestion'): m2o_fields = [name for name, field in self._fields.items() if field.type == 'many2one'] if m2o_fields: xpath_query = " | ".join(f".//field[@name='{name}']" for name in m2o_fields) nodes = arch.xpath(xpath_query) self._modify_m2o_field_option(nodes) return arch, view

Why self._context.get('mi_gestion') Fails

In Odoo, self._context is derived from self.env.context. But in _get_view(), self is often just the bare model class (env['your.model']), not a recordset, so it doesn't carry the dynamic context from the view request.


i hope it is use full



Avatar
Zrušit
Autor

Hello,
Thank you for your response. I tried your code, but unfortunately, I'm not receiving any context values in the options parameter. Here's what I currently get in options:

{'action_id': 149, 'embedded_action_id': False, 'embedded_parent_res_id': False, 'load_filters': True, 'toolbar': True}

Could you please assist me further with this? It's really important for what I'm trying to achieve.

@api.model
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
res = super().fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)

if view_type == 'form' and self.env.context.get('mi_gestion'):
doc = etree.XML(res['arch'])
m2o_fields = [name for name, field in self._fields.items() if field.type == 'many2one']
if m2o_fields:
xpath_query = " | ".join(f".//field[@name='{name}']" for name in m2o_fields)
nodes = doc.xpath(xpath_query)
self._modify_m2o_field_option(nodes) # <- Your custom method
res['arch'] = etree.tostring(doc, encoding='unicode')

return res
If you're passing mi_gestion=True from a client-side JS widget or form, make sure it's in the right place.
Example :
this.do_action({
type: 'ir.actions.act_window',
name: 'Custom Form',
res_model: 'your.model',
views: [[false, 'form']],
target: 'current',
context: {
mi_gestion: true,
}
});
try this way
i hope it will help

Related Posts Odpovědi Zobrazení Aktivita
1
srp 25
1565
1
srp 25
538
0
čvc 25
688
0
čvc 25
1259
1
kvě 25
1773