16. Desarrollando con Odoo (11). XXXX completar domain is_dev comparado con is_padron !!!!! Repasando conceptos importantes: compute, default, ref, eval, context, domain, env, search, create. i18n _. Vistas heredadas en nueva vista

0. Introducción

Aquí se veran conceptos muy útiles que se han dado anteriormente y que conviene reforzar:


1. Incluir dependencias a odoo

Se vió en ese post y se indican en __manifest__.py

"external_dependencies": {"python": ["unidecode", "cryptography"]},

 

2. Domain y context. default_field. 

En un blog anterior y otro blog anterior, domain se utiliza para filtrar registros, mientras que context se utiliza para dar valores por defecto o indicar la vista que hay que abrir

Los utilizábamos en action(1) y referenciando una vista(2) desde un campo many2one.

2.1 Domain y context en action

En una action (1), filtrando por el campo is_dev (y además estableciendo dicho campo por defecto, utilizando context y default) :

    <!-- D E V E L O P E R  -->
    <!-- Accion primaria--> 
    <record model="ir.actions.act_window" id="ximoapp01.action_developer_window">
      <field name="name">ximoapp01 developer window</field>
      <field name="res_model">res.partner</field>
      <field name="view_mode">tree,form</field>
      
      <field name="domain">[('is_dev','=',True)]</field>
      <field name="context">{'default_is_dev':True}</field>
      
    </record>


2.2 Domain y context al llamar una vista desde un campo (en una vista)

En una vista(2) que llamamos desde un campo


    <!-- 1.2 FORM explicit list view definition -->
    <record model="ir.ui.view" id="ximoapp01.task_form">
      <field name="name">ximoapp01 task form</field>
      <field name="model">ximoapp01.task</field>
      <field name="arch" type="xml">
        <form>
          <group>
            <field name="name"/>
            <field name="history"/>
            <field
              name= "developers"
              domain="[('is_dev','=',True)]"
              context="{'form_view_ref':'ximoapp01.developer_form'}">
            </field>
          </group>
        </form>
      </field>
    </record>

    

2.3 Context para crear variables en el contexto (desde la vista)  y utilizarlas en el modelo

como se vio en este blog, con context podemos crear variables y asignarles un valor que luego pueden ser utilizadas en el modelo (normalmente para asignar valores a algún campo)


<field name="tasks"
       context="{'current_developer':active_id}">
</field>

En el modelo de task , creamos una función antes de la definición del campo developers que se llame _get_default_developer, que obtenga el developer y retorne su id.

A continuación en dicho modelo, le decimos que el campo developer tiene un default que apunta a dicha función

    def _get_default_developer(self):
        developer= self.browse(self._context.get('current_developer'))
        if developer:
            return [developer.id]
        else:
            return []
    
    developers = fields.Many2many(comodel_name="res.partner", 
                                  relation="partner_task", 
                                  column1="task_id", 
                                  column2="partner_id", 
                                  default=_get_default_developer, 
                                  help="Desarrolladores")

2.4 Filtrar en un tab (page)

Vimos en este blog anterior como crear un "tab", que solo se mostrara si el campo is_dev es True

    <!-- D E V E L O P E R  --> 
    <record model="ir.ui.view" id="ximoapp01.developer_form">
      <field name="name">ximoapp01 developer form</field>
      <field name="model">res.partner</field>
      <field name="inherit_id" ref="base.view_partner_form"></field>
      <field name="mode">primary</field>
      <field name="arch" type="xml">
        <xpath expr="//sheet/notebook/page[@name='internal_notes']" position = 'after'>
          <page name="devs" string="Devs" attrs="{'invisible':[('is_dev','=',False)]}">
            <group>
              <group>
                <field name="is_dev"/>
                <field name="technologies"/>
              </group>  
            </group>
          </page>
        </xpath>
      </field>  
    </record>

3. Default y default_field. Funciones lambda. compute

3.1 default y default_field 

Como recordatorio, al definir un campo en un modelo podemos aplicar el atributoi del campo "default" y asignarle un valor por defecto, o pasarle una funcioón definida mas arriba que le calvule el valor por defecto. En cambio default_field (default_is_dev...) , se aplica en el context para estableer un valor a tomar al abrir la vista que se describe.

El valor default calculado mediante una función se puede hacer de dos maneras:
  1. Como hemos dicho, definiendo una función antes de la definición del campo en el modelo 
  2. En el atributo default, pasarle una función lambda

3.2 compute

El atributo compute de un campo en el modelo le indicamos la función "entre comillas", al contario que el atributo default

4. Variable "__name__"

Se vio al hablar de loggers e indica en este caso el nombre del fichero de logs que se ha definido en la configuración de Odoo "odoo.conf"

5. Error en @api_depends('id'))

Si metemos esto en el model, ODOO NO ARRANCA. Odoo solo acepta este decorador en campos que estánmeidos en el modelo, y aunque Odoo mete id internaente, NO SE PUEDE Utilizar así. Para salvar este escollo, se puede hacer @api_depends("campo_truco"), donde campo_truco es un campo de solo lectura que se le da un valor al crear el registro, por tanto solo se producirá el cambio de avlor al crear el registro, aligual que el campo id

6. active_id

Este prámetro se utiliza en una view para meterlo en el context y desde el modelo a llamar se puede leer. Se vió en el apartado 2.3


7. origin

Se utiliza para obtener el id cuando no está disponible. Esta sdituación se produce cuando estamos dando de alta registros de vistas anidadss que se llaman en cadena y la últina no tiene constancia del id del padre inmediato que lo ha llamado. Para ello comprobamos que si el  campo buscado sea de tipo models.NewId entonces debe coger el valor de origin

    if isinstance(record.history.project.id, models.NewId):
      id_project= int (record.history.id.origin)
    else:
      id_project= record.history.id

8. self.env

self.env tiene un montón de facetas:

8.1 search

Para buscar en un modelo dada una condición y devuelve una lista. Ver mas detalles en una futura entrada.

sprints = self.env['ximoapp01.sprint'].search(\ 
  [('project.id', '=', record.history.project.id)])

 En este caso busca los registros del modelo ximoapp01.sprint  que cumplan project.id sea igual a al campo history.project.id del registro que estamos tratando, y devuleve una lista llamada sprints

8.2 create

Para crear un registro y le pasamos un json con los valores del nuevo registro

categ = self.env['res.partner.category'].create({'name':'Devs'})  

9. i18n

La internacionalización en Odoo se realiza con el módulo "_"

por eso en los módulos aparece 

from odoo import _

Y se suele utilzar así al realizar comprobaciones

from odoo import _
--------

raise ValidationError(_('At least one language must be active.'))

10. Reutilizar una vista (herencia). xpath

10.1 xpath

Mediante el xpath localizamos el campo anterior al que queremos meter y tras buscar el nombre en modo desarrollador tal como hicimos en este post, lo añadimos:

<record model="ir.ui.view" id="ximoapp01.improvement.inherited_form">
    <field name="name">ximoapp01 improvement form</field>
    <field name="model">ximoapp01.improvement</field>
    <field name="arch" type="xml">
        <xpath expr="//field[@name='vat']" position="after">
            <field name="new_field"/>
        </xpath>
    </field>
</record>

10.2 ¿Vista nueva (mode=primary) u original ampliada ?

Si metemos mode primary entonces tendremos una nueva vista si no lo hacemos, estamos ampliando la original.


<record model="ir.ui.view" id="ximoapp01.improvement.inherited_form">
    <field name="name">ximoapp01 improvement form</field>
    <field name="model">ximoapp01.improvement</field>
    <field name="inherit_id" ref="ximoapp01.improvement"/>
    <field name="mode">primary</field>
<field name="arch" type="xml"> <xpath expr="//field[@name='vat']" position="after"> <field name="new_field"/> </xpath> </field> </record>




Comentarios

Entradas populares de este blog

20. Desarrollando con Odoo (15). Permisos y grupos. Crear usuarios de la aplicación. Restringir permisos a usuarios

2. El Modo desarrollador

8. Desarrollando con Odoo (6). Herencia de clase en modelos. Herencia de vistas. Operaciones numeradas en Odoo ??