Ocultar/Mostrar columnas en un treeview de un campo One2many en Odoo 8

2,287 views
Skip to first unread message

Juan I. Ortiz

unread,
Oct 24, 2017, 10:45:51 AM10/24/17
to Usuarios Odoo / OpenERP en España
Hola,

¿sabéis si hay alguna forma de ocultar/mostrar una columnas en una vista treeview de un campo One2many en un formulario?

Es decir, por ejemplo, imaginamos que tenemos un modelo de "peliculas" (name, tipo, director, pais) y tipo puede ser terror, acción, otros. Y tenemos un campo One2many de "escenas" (minuto, fecha, name, num_actores, contiene_efectos, contiene_musica). Queremos que en la vista formulario de "pelicula" aparezca todos los campos de pelicula y aparezca una tabla relacionada con "escenas" y para ello, usamos el widget "one2many_list", y queremos que la vista <tree> relacionada, muestra unas columnas u otras del modelo escena según el tipo de película sea de terror o no.

He probado introducir dos veces el field "escenas ", añadiendo un attrs="{'invisible' : [('tipo', '=', 'terror')]}" o attrs="{'invisible' : [('tipo', '!=', 'terror')]}" según quiera mostrar unas columnas u otras, pero en ese caso siempre me renderiza el formulario las columnas definidas en el último field. Os pongo un ejemplo de esto, que es un poco confuso.

--Extracto de mi vista que no funciona ---

<field name="arch" type="xml">
 <form>
<field name="name"/>
<field name="tipo" />
<field name="director"/>
<field name="pais"/>

<field name="escenas"widget="one2many_list" attrs="{'invisible' : [('tipo', '!=', 'terror')]}">
<tree editable="bottom"  >
    <field name="minuto"/>
    <field name="fecha"/>
    <field name="name"/>
 </tree>
 </field>

<field name="escenas"widget="one2many_list" attrs="{'invisible' : [('tipo', '=', 'terror')]}">
<tree editable="bottom"  >
    <field name="minuto"/>
    <field name="fecha"/>
    <field name="name"/>
    <field name="num_actores"/>
    <field name="contiene_efectos"/>
 </tree>
 </field>
....

Con esto no se soluciona lo que busco.

Igual podría existir una solución usando fields_get o fields_view_get o no sé...

Gracias por vuestra ayuda!

cubells

unread,
Oct 24, 2017, 11:06:04 AM10/24/17
to openerp-s...@googlegroups.com
El 24/10/17 a les 16:45, Juan I. Ortiz ha escrit:
> Hola,
>
> ¿sabéis si hay alguna forma de ocultar/mostrar una columnas en una vista
> treeview de un campo One2many en un formulario?

Debe de haber definida una vista tree para el model de datos de la
vista, aunque te parezca que no.

La vista tree puede estar definida en tu módulo o en otro módulo o en el
módulo original. Haz herencia de la vista tree y modifica.

Si no existe esa vista tree la deberás de definir en tu modelo. Este
caso ya és más raro.


--
Atentament, cubells.
--

Juan I. Ortiz

unread,
Oct 24, 2017, 12:10:53 PM10/24/17
to Usuarios Odoo / OpenERP en España
Hola cubells,

me refería a mostrar/ocultar de forma "dinámica y condicional" una columna en función del valor de un campo dentro del modelo raíz, dentro de un <tree>.

No se si lo entiendo bien, pero creo que la vista tree que define los campos a mostrar de la relación One2many están incluidas dentro de la vista form.

Alguien alguna idea?

Gracias.

cubells

unread,
Oct 24, 2017, 12:53:59 PM10/24/17
to openerp-s...@googlegroups.com
El 24/10/17 a les 18:10, Juan I. Ortiz ha escrit:
> Hola cubells,
>
> me refería a mostrar/ocultar de forma "dinámica y condicional" una
> columna en función del valor de un campo dentro del modelo raíz, dentro
> de un <tree>.
>

Yo lo que hacía en ese caso, era añadir un campo al modelo hijo que
dependa del campo del padre, así se actualiza cuando el campo del padre
se actualiza. Despues en la vista añadía el attrs adecuado dependiendo
de ese campo del modelo hijo.


> No se si lo entiendo bien, pero creo que la vista tree que define los
> campos a mostrar de la relación One2many están incluidas dentro de la
> vista form.


Depende del programador. Lo puedes definir en el propio campo one2many
con un tree,
https://github.com/OCA/OCB/blob/8.0/addons/account/account_invoice_view.xml#L356

o puedes definirlo aparte en una vista tree separada.
https://github.com/camptocamp/c2c-rd-addons/blob/8.0/picking_invoice_rel/invoice_view.xml#L13

Lo más normal es el primer caso, claro, pero no es necesario.

--
Atentament, cubells.
--

Juan I. Ortiz

unread,
Oct 25, 2017, 4:12:53 AM10/25/17
to Usuarios Odoo / OpenERP en España
Hola cubells,

perdona, pero no consigo que funcione desde el xml.

He probado usando la función fields_view_get() en la clase "peliculas", para interceptar y luego modificar el contenido de la vista form de mi xml, pero resulta que parece que no es ahí donde se renderiza el <tree> dentro del <field name="escenas" widget="one2many_list" />, es decir, en vez de mostrar:



<field name="escenas" widget="one2many_list"">
<tree editable="bottom"  >
    <field name="minuto"/>
    <field name="fecha"/>
    <field name="name"/>
 </tree>
 </field>

muestra:

<field name="escenas" widget="one2many_list"">

 </field>

Alguien sabe cuando genera el contenido del one2many_list o donde puedo interceptar la creación del widget, que imagino que será por ahí  por donde van los tiros...

¿Alguna otra opción para mostrar/ocultar columnas de un field One2many con un widget one2many_lis, de forma condicional?

Saludos.

victor...@kayuulab.com

unread,
Oct 25, 2017, 8:05:52 AM10/25/17
to Usuarios Odoo / OpenERP en España
Hola Juan,

Yo creo que el tema es seguir el ejemplo de account_invoice que te ha mandado Cubells, si te fijas el detalle de que columna se ve o no se pone en la propia columna, en ese ejemplo usa a veces un domain  y en otros también un group, por si algún campo lo puede ver solo un grupo de gente (pe el editor de la peli en tu caso). Podría quedar así (ojo, no lo he probado), suponiendo que quieres ver si  hay escenas de boda solo en las películas tipo drama o románticas y ver donde están las escenas de zombies solo en las de terror:


<field name="arch" type="xml">
 <form>
<field name="name"/>
<field name="tipo" />
<field name="director"/>
<field name="pais"/>


<field name="escenas"widget="one2many_list" >
<tree editable="bottom"  >
    <field name="minuto"/>
    <field name="fecha"/>
    <field name="name"/>
    <field name="escena_boda" domain="[ ('tipo','in',['drama','romantica'])]" />
    <field name="escena_zombi" domain="[ ('tipo','in',['terror'])]" />
 </tree>
 </field>



Saludos,

Victor

Juan I. Ortiz

unread,
Oct 25, 2017, 8:05:59 AM10/25/17
to Usuarios Odoo / OpenERP en España
Hola,

he encontrado una solución usando la función fields_view_get(). Os desarrollo un poco los pasos y la lógica que he seguido hasta llegar a ella.

Consideraciones previas:

1º- Cuando en nuestro form usamos un field de un campo One2many y usamos el widget="one2many_list", parece que si dentro del field anidamos la estructura <tree> que queremos que muestre, usa esta estructura. Si no ponemos ninguna estructura, entonces usa la vista tree que tenga configurada el sistema o que hayamos definido nosotros de forma explicita en un archivo xml.

2º- Usando la función fields_view_get(), cuando interceptamos la vista form y vemos el contenido, no sé por qué, pero si el field One2many, en el xml tiene definido su vista tree de forma anidada, esta no aparece, por lo tanto, no se puede modificar.

3º- La vista form, con su field One2many, con tree anidado, no lanza la funcion fields_view_get() del modelo con el que se relaciona el campo One2many.

4º- La vista form, con su field One2many, pero sin ningún tree anidado, si el sistema dispone de una vista tree registrada de ese modelo con el que se relaciona el campop One2many, entonces si lanza la funcion fields_view_get(). Además, esta función, si gestiona la información que se renderiza cuando el field One2many, hace uso del widget "one2many_list".

Después de este rollo, que no sé si es del todo cierto, porque está basado en prueba y error, al final lo que he hecho respecto a mi supuesto inicial, es lo siguiente, partiendo de que tenemos dos modelos, peliculas y escenas, y que su relación es de One2many.

Vistas generadas

Vista de tipo form para el modelo pelicula...
<record...


<field name="arch" type="xml">
 <form>
<field name="name"/>
<field name="tipo" />
<field name="director"/>
<field name="pais"/>

<field name="escenas"widget="one2many_list" context="{'default_tipo': tipo}" />

</form>

Vista tree de escenas
<record...>

<field name="arch" type="xml">
<tree editable="bottom"  >
    <field name="minuto"/>
    <field name="fecha"/>
    <field name="name"/>
    <field name="num_actores" invisible="1" />
    <field name="contiene_efectos" invisible="1" />
</tree>
</field>

Dentro de la clase del modelo de escenas:

class Escenas(models.Model):

....

class Escena(models.Model):
    _inherit
='escenas'

   
[Campos del modelo...]

   
@api.model
   
def fields_view_get(self, view_id=None, view_type=False, toolbar=False, submenu=False):
        context
= self._context

        tipo_pelicula
= context.get('default_tipo')
       
        res
= super(Escena, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)

       
if view_type == 'tree':
            doc
= etree.XML(res['arch'])

           
if tipo_escena in ('terror'):
               
for node in doc.xpath("//field[@name='num_actores']"):
                    node
.set('invisible', '0')
                    node
.set('modifiers', '{"tree_invisible": false}')
               
for node in doc.xpath("//field[@name='contiene_efectos']"):
                    node
.set('invisible', '0')
                    node
.set('modifiers', '{"tree_invisible": false}')
         
        res
['arch'] = etree.tostring(doc)
       
return res


La clave un poco está en modificar el nodo buscandolo por su propiedad name y añadir los atributos que queramos... La propiedad que realmente hace que se vea o no una columna es la de modifiers... Con solo invisible, seguía haciendo que se modificase.

Perdón por el lío, pero creo que puede ser de utilidad.

Espero que se entienda algo.

Saludos.





Reply all
Reply to author
Forward
0 new messages