• No se han encontrado resultados

Odoo10 -Construccion Modulo

N/A
N/A
Protected

Academic year: 2021

Share "Odoo10 -Construccion Modulo"

Copied!
43
0
0

Texto completo

(1)

Construcción de modulo en Odoo 10

Construcción de modulo en Odoo 10

Iniciar/detener el servidor Odoo

Iniciar/detener el servidor Odoo

Odoo utiliza una arquitectura cliente / servidor en el que los clientes son los navegadores web que acceden al Odoo utiliza una arquitectura cliente / servidor en el que los clientes son los navegadores web que acceden al servidor Odoo a través de RPC.

servidor Odoo a través de RPC.

La lógica de negocio y la extensión se lleva a cabo generalmente en el lado del servidor, aunque apoyan las La lógica de negocio y la extensión se lleva a cabo generalmente en el lado del servidor, aunque apoyan las funciones del cliente (por ejemplo, una nueva representación de datos tales como mapas interactivos) puede ser funciones del cliente (por ejemplo, una nueva representación de datos tales como mapas interactivos) puede ser añadido al cliente.

añadido al cliente.

Con el fin de iniciar el servidor, basta con invocar el comando

Con el fin de iniciar el servidor, basta con invocar el comando odoo-bin odoo-bin en la cáscara, la adición de la ruta completa alen la cáscara, la adición de la ruta completa al archivo si es necesario:

archivo si es necesario:

odoo

odoo-- binbin

El servidor es detenido por golpear

El servidor es detenido por golpear Ctrl-CCtrl-Cdos veces desde el terminal, o matando el proceso OS correspondiente.dos veces desde el terminal, o matando el proceso OS correspondiente.

Construir un módulo Odoo

Construir un módulo Odoo

 Ambas

 Ambas extensiones extensiones de de servidor servidor y cy cliente liente se se empaquetan empaquetan comocomo módulosmódulos que se cargan opcionalmente en una que se cargan opcionalmente en una basebase de datos

de datos..

Los módulos Odoo puede agregar nueva lógica de negocio a un sistema, o modificar y ampliar la lógica de negocio Los módulos Odoo puede agregar nueva lógica de negocio a un sistema, o modificar y ampliar la lógica de negocio existente: un módulo puede ser creado para añadir reglas de contabilidad de su país para el apoyo de la contabilidad existente: un módulo puede ser creado para añadir reglas de contabilidad de su país para el apoyo de la contabilidad general de Odoo, mientras que el siguiente módulo añade soporte para la visualización en tiempo real de una flota de general de Odoo, mientras que el siguiente módulo añade soporte para la visualización en tiempo real de una flota de autobuses. Todo en Odoo por lo tanto comienza y termina con módulos.

autobuses. Todo en Odoo por lo tanto comienza y termina con módulos.

Composición de un módulo

Composición de un módulo

Un módulo

Un módulo Odoo Odoo puede contener una puede contener una serie de elementos:serie de elementos:

Objetos de negocio (

Objetos de negocio (Business objectsBusiness objects))

Declarado como clases de Python, estos recursos se conservan automáticamente por Odoo basado en su Declarado como clases de Python, estos recursos se conservan automáticamente por Odoo basado en su configuración

configuración

Archivos de información (

Archivos de información (Data filesData files))

XML o CSV archivos de metadatos que declaran (vistas o flujos de trabajo), los datos de configuración (módulos XML o CSV archivos de metadatos que declaran (vistas o flujos de trabajo), los datos de configuración (módulos de parametrización), datos de demostración y más

de parametrización), datos de demostración y más

Controladores web (

Controladores web (Web controllersWeb controllers))

Manejar las solicitudes de los navegadores Web Manejar las solicitudes de los navegadores Web

Datos de la web estática (

Datos de la web estática (Static web dataStatic web data))

Imágenes, archivos CSS o Javascript empleado por la interfaz web o sitio web Imágenes, archivos CSS o Javascript empleado por la interfaz web o sitio web

Estructura del módulo

Estructura del módulo

Cada módulo es un directorio dentro de un

Cada módulo es un directorio dentro de un directorio de módulosdirectorio de módulos. Los directorios módulo se especifican mediante el uso de la. Los directorios módulo se especifican mediante el uso de la -- --addons-path

addons-pathopción.opción.

Tip

Tip

La mayoría de las opciones de línea de comandos también se pueden configurar mediante

La mayoría de las opciones de línea de comandos también se pueden configurar mediante

un a

un a

rchi

rchi

vo

vo

de

de

config

config

uración

uración

..

Un módulo Odoo se declara por su

Un módulo Odoo se declara por su manifiesta manifiesta(manifest). Consulte la(manifest). Consulte la documentación de manifiesto documentación de manifiestoal respecto.al respecto. Un módulo es también un

Un módulo es también unpaquete paquete de de PythonPythoncon un archivocon un archivo__init__.py__init__.py, que contiene instrucciones de, que contiene instrucciones de importación para diversos archivos de Python en el módulo.

importación para diversos archivos de Python en el módulo. Por ejemplo, si el módulo tiene un solo

Por ejemplo, si el módulo tiene un solomymodule.pymymodule.py archivoarchivo__init__.py__init__.py puede contener: puede contener: from

from .. importimport mymodulemymodule

Odoo proporciona un mecanismo para ayudar a configurar un nuevo módulo,

Odoo proporciona un mecanismo para ayudar a configurar un nuevo módulo,  odoo-bin odoo-bin tiene untiene un subcomando

subcomando scaffoldscaffold para crear un módulo vacío:para crear un módulo vacío:

$

(2)

El comando crea un subdirectorio para su módulo, y crea automáticamente un montón de archivos estándar para un El comando crea un subdirectorio para su módulo, y crea automáticamente un montón de archivos estándar para un módulo. La mayoría de ellos simplemente contener código XML o comentado. El uso de la mayor parte de esos módulo. La mayoría de ellos simplemente contener código XML o comentado. El uso de la mayor parte de esos archivos se explicará a lo largo de este tutorial.

archivos se explicará a lo largo de este tutorial.

Ejercicio Ejercicio

Creación de módulos Creación de módulos

Utilice la línea de comandos anterior para crear un módulo vacío abierto Academia, e instalarlo en Odoo. Utilice la línea de comandos anterior para crear un módulo vacío abierto Academia, e instalarlo en Odoo.

1.

1. Invocar Invocar el el comandocomando odoo-bin scaffold openacademy addonsodoo-bin scaffold openacademy addons.. 2.

2. Adaptar Adaptar el el archivo archivo de de manifiesto manifiesto a a su su módulo.módulo. 3.

3. No No preocuparse preocuparse por por los los demás demás archivos.archivos.

Mapeo

Mapeo

objeto-relac

objeto-relac

ional

ional

Un componente clave de Odoo es la capa ORM. Esta capa evita tener que escribir la mayor parte de SQL con la Un componente clave de Odoo es la capa ORM. Esta capa evita tener que escribir la mayor parte de SQL con la mano y proporciona servicios de extensibilidad y seguridad (

mano y proporciona servicios de extensibilidad y seguridad (  2 2 ).).

Los objetos de negocio se declaran como clases de Python que se extienden

Los objetos de negocio se declaran como clases de Python que se extienden ModelModel,, que los integra en el sistema que los integra en el sistema automatizado de persistencia.

automatizado de persistencia.

Los modelos pueden ser configurados mediante el establecimiento de una serie de atributos bajo su definición. El Los modelos pueden ser configurados mediante el establecimiento de una serie de atributos bajo su definición. El atributo más importante es

atributo más importante es _name _name que se requiere y define el nombre para el modelo en el sistema Odoo. He aquíque se requiere y define el nombre para el modelo en el sistema Odoo. He aquí una definición mínimamente completa de un modelo:

una definición mínimamente completa de un modelo:

from

from odooodoo importimport modelsmodels

class

class MinimalModelMinimalModel(models(models..Model):Model):

_name

_name == 'test.model''test.model'

Campos del modelo

Campos del modelo

Los campos que se utilizan para definir lo que el modelo puede almacenar y dónde. Los campos son definidos como Los campos que se utilizan para definir lo que el modelo puede almacenar y dónde. Los campos son definidos como atributos en la clase del modelo:

atributos en la clase del modelo:

from

from odooodoo importimport models,models, fieldsfields

class

class LessMinimalModelLessMinimalModel(models(models..Model):Model):

_name

_name == 'test.model2''test.model2'

name

name == fieldsfields..Char()Char()

Los atributos comunes

Los atributos comunes

 Al igual que el modelo en sí, sus campos se pueden configurar, mediante el paso

 Al igual que el modelo en sí, sus campos se pueden configurar, mediante el paso de configuración de atributos comode configuración de atributos como parámetros:

parámetros:

name

name == fieldfield..Char(requiredChar(required==True)True)

 Algunos atributos están disponibles en todos los campos, estos son los más comunes:  Algunos atributos están disponibles en todos los campos, estos son los más comunes:

string( unicode, Por defecto: el nombre del campo) string( unicode, Por defecto: el nombre del campo)

La etiqueta del campo en la interfaz de usuario (visible por los usuarios). La etiqueta del campo en la interfaz de usuario (visible por los usuarios).

required( bool, Por defecto: False) required( bool, Por defecto: False)

Si el campo

Si el campo TrueTrue no puede estar vacío, o bien debe tener un valor por defecto o que siempre se le da un no puede estar vacío, o bien debe tener un valor por defecto o que siempre se le da un valor al crear un registro.

valor al crear un registro.

help( unicode, Por defecto: '') help( unicode, Por defecto: '')

Formato largo, proporciona una información sobre herramientas ayuda a los usuarios en la interfaz de Formato largo, proporciona una información sobre herramientas ayuda a los usuarios en la interfaz de usuario.

usuario.

index( bool, Por defecto: False) index( bool, Por defecto: False)

Pide que Odoo crear un

Pide que Odoo crear un índice de base de datos índice de base de datos en la columna.en la columna. Por defecto en Odoo se escribe default.

(3)

Campos simples

Campos simples

Hay dos amplias categorías de campos: campos "simples", que son valores atómicos almacenados directamente en Hay dos amplias categorías de campos: campos "simples", que son valores atómicos almacenados directamente en la mesa del modelo y campos "relacionales" vinculación de registros (del mismo modelo o de diferentes modelos). la mesa del modelo y campos "relacionales" vinculación de registros (del mismo modelo o de diferentes modelos). Ejemplo de campos simples son

Ejemplo de campos simples son BooleanBoolean,,DateDate,, Char Char ..

Campos reservados

Campos reservados

Odoo crea algunos campos en todos los modelos (

Odoo crea algunos campos en todos los modelos (  1 1 ). Estos campos son gestionados por el sistema y no se deben). Estos campos son gestionados por el sistema y no se deben escribirse. Pueden ser leídos si útil o necesario:

escribirse. Pueden ser leídos si útil o necesario:

id

id(( IdId))

El identificador único para un registro en su modelo. El identificador único para un registro en su modelo.

create_date

create_date(( DatetimeDatetime))

Fecha de creación del registro. Fecha de creación del registro.

create_uid

create_uid(( Many2oneMany2one))

Usuario que creó el registro. Usuario que creó el registro.

write_date

write_date(( DatetimeDatetime))

Fecha de la última modificación del registro. Fecha de la última modificación del registro.

write_uid

write_uid(( Many2oneMany2one))

Usuario que modificó por última vez el registro. Usuario que modificó por última vez el registro.

Los

Los

cam

cam

pos

pos

especia

especia

le

le

s

s

Por defecto, Odoo también requiere un campo

Por defecto, Odoo también requiere un campo namename en todos los modelos para diferentes comportamientos deen todos los modelos para diferentes comportamientos de visualización y búsqueda. El campo que se utiliza para estos fines puede ser anulado por el ajuste

visualización y búsqueda. El campo que se utiliza para estos fines puede ser anulado por el ajuste _rec_name _rec_name..

Ejercicio

Ejercicio

Definir un modelo

Definir un modelo

Definir un nuevo modelo de datos

Definir un nuevo modelo de datos

curso

curso

 en el módulo

 en el módulo

openacademy 

openacademy 

. Un curso tiene un título y una

. Un curso tiene un título y una

descripción. Los cursos deben tener un título.

descripción. Los cursos deben tener un título.

Editar el archivo

Editar el archivo

openacademy/models/models.pyopenacademy/models/models.py

para incluir un

para incluir un

curso

curso

 de clases.

 de clases.

openacademy/models.py

openacademy/models.py

from

from odooodoo importimport models,models, fields,fields, apiapi

class

class CourseCourse(models(models..Model):Model):

_name

_name == 'openacademy.course''openacademy.course'

name

name == fieldsfields..Char(stringChar(string=="Title""Title",, requiredrequired==True)True)

description

description == fieldsfields..Text()Text()

 Archivo

 Archivo

s de inf

s de inf

ormación

ormación

Odoo es un sistema altamente impulsado por datos. Aunque el comportamiento se personaliza mediante código Odoo es un sistema altamente impulsado por datos. Aunque el comportamiento se personaliza mediante código Python, una parte del valor de un módulo se encuentra en los datos que establece al cargarse.

Python, una parte del valor de un módulo se encuentra en los datos que establece al cargarse.

Tip

Tip Existen algunos módulos únicamente para añadir datos en OdooExisten algunos módulos únicamente para añadir datos en Odoo Los módulos de datos se declara a través de

Los módulos de datos se declara a través de data filesdata files,,  archivos XML con elementos  archivos XML con elementos <record><record>. Cada. Cada elemento

elemento <record><record>crea o actualiza un registro de base de datos.crea o actualiza un registro de base de datos.

<odoo>

<odoo>

<data>

<data>

<record

<record model=model="{model name}""{model name}" id=id="{record identifier}""{record identifier}">>

<field

<field name=name="{a field name}""{a field name}">>{a value}{a value}</field></field>

</record> </record> </data> </data> </odoo> </odoo>

(4)

 modelmodel es el nombre del modelo Odoo para el registro. es el nombre del modelo Odoo para el registro.

 idides unes un identificador externoidentificador externo, permite referír al registro (sin necesidad de conocer su identificador en la base, permite referír al registro (sin necesidad de conocer su identificador en la base de datos).

de datos).

 <field><field> elementos tienen unelementos tienen un namename que es el nombre del campo en el modelo (por ejemploque es el nombre del campo en el modelo (por ejemplo descriptiondescription). Su). Su cuerpo es el valor del campo.

cuerpo es el valor del campo.

Los archivos de información tienen que ser declarados en el archivo de manifiesto para ser cargados, pueden ser Los archivos de información tienen que ser declarados en el archivo de manifiesto para ser cargados, pueden ser declaradas en la lista

declaradas en la lista'data''data' (siempre cargado) o en la lista (siempre cargado) o en la lista 'demo''demo' (sólo se cargan en modo de demostración). (sólo se cargan en modo de demostración).

Ejercicio

Ejercicio

Definir los datos de

Definir los datos de

demostrac

demostrac

ión

ión

Crear datos de demostración llenando el modelo de Cursos con unos cuantos cursos de demostración.

Crear datos de demostración llenando el modelo de Cursos con unos cuantos cursos de demostración. Editar elEditar el archivo

archivoopenacademy/demo/demo.xmlopenacademy/demo/demo.xmlpara incluir algunos datos.para incluir algunos datos.

openacademy/demo.xml 

openacademy/demo.xml 

<odoo> <odoo> <data> <data> <record

<record model=model="openacademy.course""openacademy.course" id=id="course0""course0">> <field

<field name=name="name""name">>Course 0Course 0</field></field> <field

<field name=name="description""description">>Course 0's descriptionCourse 0's description Can have multiple lines

Can have multiple lines </field> </field> </record> </record> <record

<record model=model="openacademy.course""openacademy.course" id=id="course1""course1">> <field

<field name=name="name""name">>Course 1Course 1</field></field> <!-- no description for this one -->

<!-- no description for this one -->

</record> </record> <record

<record model=model="openacademy.course""openacademy.course" id=id="course2""course2">> <field

<field name=name="name""name">>Course 2Course 2</field></field> <field

<field name=name="description""description">>Course 2's Course 2's descriptiodescriptionn</field></field> </record> </record> </data> </data> </odoo> </odoo>

 Acciones

 Acciones

y Menú

y Menú

s

s

 Acciones y menús son registros regulares en la base de datos, normalmente declarados a través de archivos de  Acciones y menús son registros regulares en la base de datos, normalmente declarados a través de archivos de

datos. Las acciones pueden ser activadas de tres maneras: datos. Las acciones pueden ser activadas de tres maneras:

1.

1. haciendo haciendo clic en clic en los ellos elementos de ementos de menú (vinculado menú (vinculado a accia acciones específicas)ones específicas) 2.

2. haciendo clic haciendo clic en los en los botones en las botones en las vistas (si vistas (si éstos están éstos están conectados a las conectados a las acciones)acciones) 3.

3. como como acciones acciones contextuales contextuales en en objetosobjetos

Debido a que los menús son algo complejas, para declarar hay un acceso directo

Debido a que los menús son algo complejas, para declarar hay un acceso directo <menuitem><menuitem> para para declarardeclarar una

unair.ui.menuir.ui.menuy conectarlo a la acción correspondiente con mayor facilidad.y conectarlo a la acción correspondiente con mayor facilidad.

<record

<record model=model="ir.actions.act_window""ir.actions.act_window" id=id="action_list_ideas""action_list_ideas">>

<field

<field name=name="name""name">>IdeasIdeas</field></field>

<field

<field name=name="res_model""res_model">>idea.ideaidea.idea</field></field>

<field

<field name=name="view_mode""view_mode">>tree,formtree,form</field></field>

</record>

</record>

<menuitem

<menuitem id=id="menu_ideas""menu_ideas" parent=parent="menu_root""menu_root" name=name="Ideas""Ideas" sequence=sequence="10""10"

action=

action="action_list_ideas""action_list_ideas"/>/>

Peligro

Peligro

La acción debe ser declarado antes de su correspondiente menú en el archivo XML. La acción debe ser declarado antes de su correspondiente menú en el archivo XML. Los archivos de datos se ejecutan secuencialmente, el

Los archivos de datos se ejecutan secuencialmente, el ididde la acción de la acción debe estar presente edebe estar presente en la base de n la base de datosdatos antes de que se puede crear el menú.

antes de que se puede crear el menú.

Ejercicio

Ejercicio

Definir nuevas entradas de menú

Definir nuevas entradas de menú

(5)

Definir nuevas entradas de menú para acceder a los cursos bajo la entrada del menú OpenAcademy. Un usuario Definir nuevas entradas de menú para acceder a los cursos bajo la entrada del menú OpenAcademy. Un usuario debe ser capaz de:

debe ser capaz de:

 mostrar mostrar una una lista lista de de todos todos los los cursoscursos

 crear crear / / modificar modificar cursoscursos

1. Crear

1. Crearopenacademy/views/openacademy.xmlopenacademy/views/openacademy.xmlcon una acción y los menús que desencadenan la accióncon una acción y los menús que desencadenan la acción 2.

2. Añadirlo Añadirlo a a la la listalista datadata de deopenacademy/__manifest__.pyopenacademy/__manifest__.py openacademy/__manifest__.py  openacademy/__manifest__.py  'data' 'data':: [[ # 'security/ir.model.access.csv', # 'security/ir.model.access.csv', 'templates.xml' 'templates.xml',, 'views/openacademy.xml' 'views/openacademy.xml',, ], ], # only loaded

# only loaded in demonstration modein demonstration mode

'demo' 'demo':: [[

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?> <odoo> <odoo> <data> <data> <!-- window action --> <!-- window action -->

<!--La siguiente etiqueta es una definición de

La siguiente etiqueta es una definición de acción para una "acción de acción para una "acción de ventana",ventana",

Que

Que es es una una acción acción que que abre abre una una vista vista o o un un conjunto conjunto de de vistas vistas -->-->

<record

<record model=model="ir.actions.act_window""ir.actions.act_window" id=id="course_list_action""course_list_action">> <field

<field name=name="name""name">>CoursesCourses</field></field> <field

<field name=name="res_model""res_model">>openacademy.courseopenacademy.course</field></field> <field

<field name=name="view_type""view_type">>formform</field></field> <field

<field name=name="view_mode""view_mode">>tree,formtree,form</field></field> <field

<field name=name="help""help" type=type="html""html">> <p

<p class=class="oe_view_nocontent_create""oe_view_nocontent_create">>Create the first courseCreate the first course </p> </p> </field> </field> </record> </record>

<!--Menú de nivel superior: sin padre -->

Menú de nivel superior: sin padre -->

<menuitem

<menuitem id=id="main_openacademy_menu""main_openacademy_menu" name=name="Open Academy""Open Academy"/>/> <!-- Se necesita un primer nivel en el menú del lado

<!-- Se necesita un primer nivel en el menú del lado izquierdoizquierdo

Antes de usar la acción = atributo -->

Antes de usar la acción = atributo -->

<menuitem

<menuitem id=id="openacademy_menu""openacademy_menu" name=name="Open Academy""Open Academy"

parent=

parent="main_openacademy_menu""main_openacademy_menu"/>/>

<!-- El menú siguiente debe aparecer * después de *

<!-- El menú siguiente debe aparecer * después de *

Su padre openacademy_me

Su padre openacademy_menu y * nu y * después de su *después de su *

Acción course_list_action -->

Acción course_list_action -->

<menuitem

<menuitem id=id="courses_menu""courses_menu" name=name="Courses""Courses" parent=parent="openacademy_menu""openacademy_menu"

action=

action="course_list_action""course_list_action"/>/>

<!--Ubicación completa de la

Ubicación completa de la identificaciidentificación:ón:

Action

Action = = "openacademy."openacademy.course_listcourse_list_action"_action"

No es necesario cuando es el mismo módulo -->

No es necesario cuando es el mismo módulo -->

</data> </data> </odoo> </odoo>

Basic views

Basic views

Las vistas definen la forma en que se muestran los registros de un modelo. Cada tipo de vista representa un modo de Las vistas definen la forma en que se muestran los registros de un modelo. Cada tipo de vista representa un modo de visualización (una lista de registros, un gráfico de su agregación, ...). Las vistas pueden ser solicitados ya sea de visualización (una lista de registros, un gráfico de su agregación, ...). Las vistas pueden ser solicitados ya sea de forma genérica a través de su tipo (por ejemplo,

forma genérica a través de su tipo (por ejemplo, una lista de sociosuna lista de socios  ) o específicamente a través de su ID. Para  ) o específicamente a través de su ID. Para solicitudes genéricas, se utilizará la vista con el tipo correcto y la prioridad más baja (lo que la vista de menor solicitudes genéricas, se utilizará la vista con el tipo correcto y la prioridad más baja (lo que la vista de menor prioridad de cada tipo es la vista por defecto para ese tipo).

prioridad de cada tipo es la vista por defecto para ese tipo). View inheritance

(6)

Generic view declaration

Generic view declaration

Una vista es declarado como un registro del modelo

Una vista es declarado como un registro del modelo ir.ui.viewir.ui.view. El tipo de vista está implícito en el elemento raíz. El tipo de vista está implícito en el elemento raíz del campo

del campoarcharch::

<record

<record model=model="ir.ui.view""ir.ui.view" id=id="view_id""view_id">>

<field

<field name=name="name""name">>view.nameview.name</field></field>

<field

<field name=name="model""model">>object_nameobject_name</field></field>

<field

<field name=name="priority""priority" eval=eval="16""16"/>/>

<field

<field name=name="arch""arch" type=type="xml""xml">>

<!-- view content: <form>, <tree>, <graph>, ...

<!-- view content: <form>, <tree>, <graph>, ... -->-->

</field> </field> </record> </record>

Peligro

Peligro

El contenido de la vista es XML. El campo

El contenido de la vista es XML. El campo archarch por lo tanto debe ser declarado como por lo tanto debe ser declarado como type="xml"type="xml"para serpara ser analizado correctamente.

analizado correctamente.

Tree views

Tree views

Vistas de árbol, también llamadas vistas de listas, registros de visualización en forma de tabla. Vistas de árbol, también llamadas vistas de listas, registros de visualización en forma de tabla. Su elemento raíz es

Su elemento raíz es <tree><tree>. La forma más simple de la vista de árbol se limita a enumerar todos los campos a. La forma más simple de la vista de árbol se limita a enumerar todos los campos a mostrar en la tabla (cada campo como una columna):

mostrar en la tabla (cada campo como una columna):

<tree

<tree string=string="Idea list""Idea list">>

<field

<field name=name="name""name"/>/>

<field

<field name=name="inventor_id""inventor_id"/>/>

</tree>

</tree>

Form views

Form views

Los formularios se utilizan para crear y editar registros individuales. Los formularios se utilizan para crear y editar registros individuales. Su elemento raíz es

Su elemento raíz es <form><form>. Se componen de elementos de alto nivel de la estructura (grupos, cuadernos) y. Se componen de elementos de alto nivel de la estructura (grupos, cuadernos) y elementos interactivos (botones y campos):

elementos interactivos (botones y campos):

<form

<form string=string="Idea form""Idea form">>

<group

<group colspan=colspan="4""4">>

<group

<group colspan=colspan="2""2" col=col="2""2">>

<separator

<separator string=string="General stuff""General stuff" colspan=colspan="2""2"/>/>

<field

<field name=name="name""name"/>/>

<field

<field name=name="inventor_id""inventor_id"/>/>

</group>

</group>

<group

<group colspan=colspan="2""2" col=col="2""2">>

<separator

<separator string=string="Dates""Dates" colspan=colspan="2""2"/>/>

<field

<field name=name="active""active"/>/>

<field

<field name=name="invent_date""invent_date" readonly=readonly="1""1"/>/>

</group>

</group>

<notebook

<notebook colspan=colspan="4""4">>

<page

<page string=string="Description""Description">>

<field

<field name=name="description""description" nolabel=nolabel="1""1"/>/>

</page>

</page>

</notebook>

</notebook>

<field

<field name=name="state""state"/>/>

</group> </group> </form> </form>

Exercise

Exercise

Personaliza vista form usando XML Personaliza vista form usando XML

Create your own form view for the Course object. Data displayed should be: the name and the description of the Create your own form view for the Course object. Data displayed should be: the name and the description of the course.

course.

openacademy/views/openacademy.xml 

(7)

<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?> <odoo> <odoo> <data> <data> <record

<record model=model="ir.ui.view""ir.ui.view" id=id="course_form_view""course_form_view">> <field

<field name=name="name""name">>course.formcourse.form</field></field> <field

<field name=name="model""model">>openacademy.courseopenacademy.course</field></field> <field

<field name=name="arch""arch" type=type="xml""xml">> <form

<form string=string="Course Form""Course Form">> <sheet>

<sheet> <group> <group>

<field

<field name=name="name""name"/>/> <field

<field name=name="description""description"/>/> </group> </group> </sheet> </sheet> </form> </form> </field> </field> </record> </record> <!-- window action --> <!-- window action -->

<!--The following tag is an action definition for a "window action",

The following tag is an action definition for a "window action",

Ejercicio

Ejercicio

NOTEBOOK

NOTEBOOK

En la vista Formulario de curso, coloque el campo de descripción bajo una pestaña, de manera que sea más fácil En la vista Formulario de curso, coloque el campo de descripción bajo una pestaña, de manera que sea más fácil agregar otras pestañas más adelante, con información adicional.

agregar otras pestañas más adelante, con información adicional. Modificar el formulario curso de la siguiente manera:

Modificar el formulario curso de la siguiente manera:

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<sheet> <sheet> <group> <group> <field

<field name=name="name""name"/>/> </group>

</group> <notebook> <notebook> <page

<page string=string="Description""Description">> <field

<field name=name="description""description"/>/> </page>

</page> <page

<page string=string="About""About">>

This is an example of notebooks This is an example of notebooks </page> </page> </notebook> </notebook> </sheet> </sheet> </form> </form> </field> </field>

Las vistas formulario también pueden usar plano HTML para los diseños más

Las vistas formulario también pueden usar plano HTML para los diseños más flexibles:

flexibles:

<form

<form string=string="Idea Form""Idea Form">>

<header>

<header>

<button

<button string=string="Confirm""Confirm" type=type="object""object" name=name="action_confirm""action_confirm"

states=

states="draft""draft" class=class="oe_highlight""oe_highlight" />/>

<button

<button string=string="Mark as done""Mark as done" type=type="object""object" name=name="action_done""action_done"

states=

states="confirmed""confirmed" class=class="oe_highlight""oe_highlight"/>/>

<button

<button string=string="Reset to draft""Reset to draft" type=type="object""object" name=name="action_draft""action_draft"

states=

states="confirmed,done""confirmed,done" />/>

<field

<field name=name="state""state" widget=widget="statusbar""statusbar"/>/>

</header>

</header>

<sheet>

<sheet>

<div

<div class=class="oe_title""oe_title">>

<label

<label for=for="name""name" class=class="oe_edit_only""oe_edit_only" string=string="Idea Name""Idea Name" />/>

<h1><field

<h1><field name=name="name""name" /></h1>/></h1>

</div>

</div>

<separator

<separator string=string="General""General" colspan=colspan="2""2" />/>

<group

<group colspan=colspan="2""2" col=col="2""2">>

<field

<field name=name="description""description" placeholder=placeholder="Idea description...""Idea description..." />/>

</group>

(8)

</sheet> </sheet> </form> </form>

Search views

Search views

Las Vistas de búsqueda personalizar el campo de búsqueda asociado a la vista de la lista (y otras vistas Las Vistas de búsqueda personalizar el campo de búsqueda asociado a la vista de la lista (y otras vistas agregadas). Su elemento raíz es

agregadas). Su elemento raíz es <search><search> y que están compuesto de campos que definen los campos que sey que están compuesto de campos que definen los campos que se pueden buscar en:

pueden buscar en:

<search>

<search>

<field

<field name=name="name""name"/>/>

<field

<field name=name="inventor_id""inventor_id"/>/>

</search>

</search>

Si no existe Buscar en la vista para el modelo, Odoo genera uno que sólo permite la búsqueda en el campo

Si no existe Buscar en la vista para el modelo, Odoo genera uno que sólo permite la búsqueda en el campo namename..

Ejercicio

Ejercicio

Buscar cursos Buscar cursos

Permitir la búsqueda de cursos en función de su título o su descripción. Permitir la búsqueda de cursos en función de su título o su descripción.

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

</field> </field> </record> </record> <record

<record model=model="ir.ui.view""ir.ui.view" id=id="course_search_view""course_search_view">> <field

<field name=name="name""name">>course.searchcourse.search</field></field> <field

<field name=name="model""model">>openacademy.courseopenacademy.course</field></field> <field

<field name=name="arch""arch" type=type="xml""xml">> <search>

<search> <field

<field name=name="name""name"/>/> <field

<field name=name="description""description"/>/> </search> </search> </field> </field> </record> </record> <!-- window action --> <!-- window action -->

<!--The following tag is an action definition for a "window action",

The following tag is an action definition for a "window action",

Las relaciones entre los modelos

Las relaciones entre los modelos

Un registro de un modelo puede estar relacionado con un registro de otro modelo. Por ejemplo, un registro de orden Un registro de un modelo puede estar relacionado con un registro de otro modelo. Por ejemplo, un registro de orden de venta se relaciona con un registro de cliente que contiene los datos del cliente; También se relaciona con sus de venta se relaciona con un registro de cliente que contiene los datos del cliente; También se relaciona con sus registros de línea de orden de venta

registros de línea de orden de venta

..

Ejercicio

Ejercicio

Crear un modelo de sesión Crear un modelo de sesión

Para el módulo abierto Academia, consideramos un modelo para

Para el módulo abierto Academia, consideramos un modelo para sesionessesiones: una sesión es una ocurrencia de un: una sesión es una ocurrencia de un curso impartido en un momento dado para un público determinado.

curso impartido en un momento dado para un público determinado. Crear un modelo para

Crear un modelo para las sesioneslas sesiones. Una sesión tiene un nombre, una fecha de inicio, una duración y un número de. Una sesión tiene un nombre, una fecha de inicio, una duración y un número de asientos. Añadir una acción y un elemento de menú para mostrarlos. Hacer que el nuevo modelo visible a través de asientos. Añadir una acción y un elemento de menú para mostrarlos. Hacer que el nuevo modelo visible a través de un elemento de menú.

un elemento de menú. 1.

1. Crear Crear la la claseclase de sesiónde sesión en en openacademy/models/models.pyopenacademy/models/models.py.. 2.

2. Añadir Añadir el el acceso acceso al al objeto de objeto de sesión sesión enen openacademy/view/openacademy.xmlopenacademy/view/openacademy.xml..

openacademy/models.py 

openacademy/models.py 

name

name == fieldsfields..Char(stringChar(string=="Title""Title",, requiredrequired==True)True) description

description == fieldsfields..Text()Text()

class

(9)

_name

_name == 'openacademy.session''openacademy.session'

name

name == fieldsfields..Char(requiredChar(required==True)True) start_date

start_date == fieldsfields..Date()Date() duration

duration == fieldsfields..Float(digitsFloat(digits==((66,, 22),), helphelp=="Duration in days""Duration in days")) seats

seats == fieldsfields..Integer(stringInteger(string=="Number of seats""Number of seats"))

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<!-- Full id location:

<!-- Full id location:

action="opena

action="openacademy.coucademy.course_list_actiorse_list_action"n"

It is not required when it is

It is not required when it is the same module -->the same module -->

<!-- session form view -->

<!-- session form view -->

<record

<record model=model="ir.ui.view""ir.ui.view" id=id="session_form_view""session_form_view">> <field

<field name=name="name""name">>session.formsession.form</field></field> <field

<field name=name="model""model">>openacademy.sessionopenacademy.session</field></field> <field

<field name=name="arch""arch" type=type="xml""xml">> <form

<form string=string="Session Form""Session Form">> <sheet>

<sheet> <group> <group>

<field

<field name=name="name""name"/>/> <field

<field name=name="start_date""start_date"/>/> <field

<field name=name="duration""duration"/>/> <field

<field name=name="seats""seats"/>/> </group> </group> </sheet> </sheet> </form> </form> </field> </field> </record> </record> <record

<record model=model="ir.actions.act_window""ir.actions.act_window" id=id="session_list_action""session_list_action">> <field

<field name=name="name""name">>SessionsSessions</field></field> <field

<field name=name="res_model""res_model">>openacademy.sessionopenacademy.session</field></field> <field

<field name=name="view_type""view_type">>formform</field></field> <field

<field name=name="view_mode""view_mode">>tree,formtree,form</field></field> </record>

</record> <menuitem

<menuitem id=id="session_menu""session_menu" name=name="Sessions""Sessions"

parent=

parent="openacademy_menu""openacademy_menu"

action=

action="session_list_action""session_list_action"/>/> </data> </data> </odoo> </odoo>

Nota

Nota

digits=(6, 2)

digits=(6, 2) especifica la precisión de un número float: 6 es el número total de dígitos, mientras que 2 es el númeroespecifica la precisión de un número float: 6 es el número total de dígitos, mientras que 2 es el número de dígitos después de la coma. Tenga en cuenta que da lugar a los números de un teléfono antes de la coma es un de dígitos después de la coma. Tenga en cuenta que da lugar a los números de un teléfono antes de la coma es un máximo de 4.

máximo de 4.

Relational fields

Relational fields

Los campos relacionales enlazan registros, ya sea del mismo modelo (jerarquías) o entre diferentes modelos. Los campos relacionales enlazan registros, ya sea del mismo modelo (jerarquías) o entre diferentes modelos. Los tipos de campos relacionales son:

Los tipos de campos relacionales son:

Many2one(other_mod

Many2one(other_model, ondelete='set null')el, ondelete='set null')

Un simple enlace a otro objeto: Un simple enlace a otro objeto:

print

print foofoo..other_idother_id..namename

Ver también

Ver también

foreign keys

foreign keys

One2many(ot

One2many(other_model, her_model, related_fieldrelated_field)) Una relación virtual, inversa de una

Una relación virtual, inversa de una Many2oneMany2one.. Un Un One2manyOne2manyse comporta como un contenedor dese comporta como un contenedor de registros, el acceso resulta en un conjunto (posiblemente vacío) de registros:

(10)

for

for otherother inin foofoo..other_ids:other_ids:

print

print otherother..namename

Peligro

Peligro

Debido a que una

Debido a que unaOne2manyOne2manyes una relación virtual, noes una relación virtual, no debedebe haber un campo haber un campoMany2oneMany2oneen elen el

other_model

other_model

, y su, y su nombre

nombredebedebe ser ser

related_field 

related_field 

Many2many(other_model) Many2many(other_model)

Bidireccional relación múltiple, cualquier registro en un lado puede estar relacionado con cualquier número de Bidireccional relación múltiple, cualquier registro en un lado puede estar relacionado con cualquier número de registros en el otro lado. Se comporta como un recipiente de registros, el acceso también resulta en un

registros en el otro lado. Se comporta como un recipiente de registros, el acceso también resulta en un conjunto posiblemente vacío de registros:

conjunto posiblemente vacío de registros:

for

for otherother inin foofoo..other_ids:other_ids:

print

print otherother..namename

Ejercicio

Ejercicio

las relaciones Many2one las relaciones Many2one

El uso de un many2one, modifique las

El uso de un many2one, modifique las del cursodel curso y la y la SesiónSesión modelos para reflejar su relación con otros modelos: modelos para reflejar su relación con otros modelos:

 Un Un curso curso tiene tiene unauna responsabilidad responsabilidad  del usuario; el valor de ese campo es un registro del modelo del usuario; el valor de ese campo es un registro del modelo integrado

integrado res.usersres.users..

 Una Una sesión sesión tiene tiene unun instructor instructor ; el valor de ese campo es un registro del modelo integrado; el valor de ese campo es un registro del modelo integrado res.partner res.partner ..

 Una Una sesión sesión se se relaciona relaciona con con unun supuestosupuesto; el valor de ese campo es un registro del; el valor de ese campo es un registro del modelo

modeloopenacademy.courseopenacademy.coursey no es requerido.y no es requerido.

 Adaptar Adaptar los los puntos puntos de de vista.vista. 1.

1. Añadir Añadir los los correspondientes correspondientes camposcampos Many2oneMany2one de los modelos, y de los modelos, y 2.

2. Añadirlos Añadirlos en en las las vistas.vistas.

openacademy/models.py 

openacademy/models.py 

name

name == fieldsfields..Char(stringChar(string=="Title""Title",, requiredrequired==True)True) description

description == fieldsfields..Text()Text() responsible_id

responsible_id == fieldsfields..Many2one(Many2one('res.users''res.users',, ondelete

ondelete=='set null''set null',, stringstring=="Responsible""Responsible",, indexindex==True)True)

class

class SessionSession(models(models..Model):Model): _name

_name == 'openacademy.session''openacademy.session'

start_date

start_date == fieldsfields..Date()Date() duration

duration == fieldsfields..Float(digitsFloat(digits==((66,, 22),), helphelp=="Duration in days""Duration in days")) seats

seats == fieldsfields..Integer(stringInteger(string=="Number of seats""Number of seats")) instructor_id

instructor_id == fieldsfields..Many2one(Many2one('res.partner''res.partner',, stringstring=="Instructor""Instructor")) course_id

course_id == fieldsfields..Many2one(Many2one('openacademy.course''openacademy.course',, ondelete

ondelete=='cascade''cascade',, stringstring=="Course""Course",, requiredrequired==True)True)

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<sheet> <sheet> <group> <group> <field

<field name=name="name""name"/>/> <field

<field name=name="responsible_id""responsible_id"/>/> </group>

</group> <notebook> <notebook> <page

<page string=string="Description""Description">> </field>

</field> </record> </record>

<!-- override the automatically generated list view for courses -->

<!-- override the automatically generated list view for courses -->

<record

<record model=model="ir.ui.view""ir.ui.view" id=id="course_tree_view""course_tree_view">> <field

(11)

<field

<field name=name="model""model">>openacademy.courseopenacademy.course</field></field> <field

<field name=name="arch""arch" type=type="xml""xml">> <tree

<tree string=string="Course Tree""Course Tree">> <field

<field name=name="name""name"/>/> <field

<field name=name="responsible_id""responsible_id"/>/> </tree> </tree> </field> </field> </record> </record> <!-- window action --> <!-- window action -->

<!--The following tag is an action definition for a "window action",

The following tag is an action definition for a "window action",

<form

<form string=string="Session Form""Session Form">> <sheet>

<sheet> <group> <group>

<group

<group string=string="General""General">> <field

<field name=name="course_id""course_id"/>/> <field

<field name=name="name""name"/>/> <field

<field name=name="instructor_id""instructor_id"/>/> </group>

</group> <group

<group string=string="Schedule""Schedule">> <field

<field name=name="start_date""start_date"/>/> <field

<field name=name="duration""duration"/>/> <field

<field name=name="seats""seats"/>/> </group> </group> </group> </group> </sheet> </sheet> </form> </form> </field> </field> </record> </record>

<!-- session tree/list view -->

<!-- session tree/list view -->

<record

<record model=model="ir.ui.view""ir.ui.view" id=id="session_tree_view""session_tree_view">> <field

<field name=name="name""name">>session.treesession.tree</field></field> <field

<field name=name="model""model">>openacademy.sessionopenacademy.session</field></field> <field

<field name=name="arch""arch" type=type="xml""xml">> <tree

<tree string=string="Session Tree""Session Tree">> <field

<field name=name="name""name"/>/> <field

<field name=name="course_id""course_id"/>/> </tree> </tree> </field> </field> </record> </record> <record

<record model=model="ir.actions.act_window""ir.actions.act_window" id=id="session_list_action""session_list_action">> <field

<field name=name="name""name">>SessionsSessions</field></field> <field

<field name=name="res_model""res_model">>openacademy.sessionopenacademy.session</field></field>

Ejercicio

Ejercicio

Las relaciones inversas One2Many Las relaciones inversas One2Many

Utilizando el inverso one2many campo relacional, modificar los modelos para reflejar la relación entre los cursos y Utilizando el inverso one2many campo relacional, modificar los modelos para reflejar la relación entre los cursos y sesiones.

sesiones. 1.

1. Modificar Modificar la la claseclase CourseCourse y y 2.

2. Agregar el Agregar el campo en campo en la vila vista de sta de formulario de formulario de curso.curso.

openacademy/models.py 

openacademy/models.py 

responsible_id

responsible_id == fieldsfields..Many2one(Many2one('res.users''res.users',, ondelete

ondelete=='set null''set null',, stringstring=="Responsible""Responsible",, indexindex==True)True) session_ids

session_ids == fieldsfields..One2many(One2many( 'openacademy.session'

'openacademy.session',, 'course_id''course_id',, stringstring=="Sessions""Sessions"))

class

class SessionSession(models(models..Model):Model):

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<page

<page string=string="Description""Description">> <field

(12)

</page> </page> <page

<page string=string="Sessions""Sessions">> <field

<field name=name="session_ids""session_ids">> <tree

<tree string=string="Registered sessions""Registered sessions">> <field

<field name=name="name""name"/>/> <field

<field name=name="instructor_id""instructor_id"/>/> </tree> </tree> </field> </field> </page> </page> </notebook> </notebook> </sheet> </sheet>

Ejercicio

Ejercicio

Las relaciones múltiples Many2Many Las relaciones múltiples Many2Many

Utilizando el Many2Many campo relacional, modificar la

Utilizando el Many2Many campo relacional, modificar la SesiónSesión modelo para relacionar cada sesión a un conjunto modelo para relacionar cada sesión a un conjunto de

deasistentesasistentes. Los asistentes estarán representados por los registros asociados, por lo que se relacionan con el. Los asistentes estarán representados por los registros asociados, por lo que se relacionan con el modelo integrado

modelo integradores.partner res.partner . Adaptar las vistas en consecuencia.. Adaptar las vistas en consecuencia. 1.

1. Modificar Modificar la la claseclase SessionSession y y 2.

2. agregar agregar el el campo campo en en la la vista vista formulario.formulario.

openacademy/models.py 

openacademy/models.py 

instructor_id

instructor_id == fieldsfields..Many2one(Many2one('res.partner''res.partner',, stringstring=="Instructor""Instructor")) course_id

course_id == fieldsfields..Many2one(Many2one('openacademy.course''openacademy.course',, ondelete

ondelete=='cascade''cascade',, stringstring=="Course""Course",, requiredrequired==True)True) attendee_ids

attendee_ids == fieldsfields..Many2many(Many2many('res.partner''res.partner',, stringstring=="Attendees""Attendees"))

openacademy/views/openacademy.xml 

openacademy/views/openacademy.xml 

<field

<field name=name="seats""seats"/>/> </group>

</group> </group> </group> <label

<label for=for="attendee_ids""attendee_ids"/>/> <field

<field name=name="attendee_ids""attendee_ids"/>/> </sheet> </sheet> </form> </form> </field> </field>

Herencia

Herencia

Modelo de herencia

Modelo de herencia

Odoo proporciona dos mecanismos

Odoo proporciona dos mecanismos de herenciade herencia para extender un para extender un modelo existente de modelo existente de una forma modular.una forma modular.

El primer mecanismo de herencia permite a un módulo para modificar el comportamiento de un modelo definido en El primer mecanismo de herencia permite a un módulo para modificar el comportamiento de un modelo definido en otro módulo:

otro módulo:

 añadir añadir campos campos a a un un modelo,modelo, 

 anular anular la la definición definición de de campos campos en en un un modelo,modelo, 

 añadir añadir restricciones restricciones a a un un modelo,modelo, 

 añadir añadir métodos métodos a a un un modelo,modelo, 

 reemplazar reemplazar los los métodos métodos existentes existentes en en un un modelo.modelo.

El segundo mecanismo de herencia (delegación) permite vincular cada registro de un modelo para un registro en un El segundo mecanismo de herencia (delegación) permite vincular cada registro de un modelo para un registro en un modelo padre, y proporciona un acceso transparente a los campos del registro padre.

(13)

Ver también

Ver también

_inherit _inherit _inherits _inherits

Vista herencia

Vista herencia

En lugar de modificar las vistas existentes en su lugar (sobrescribiéndolas), Odoo proporciona una herencia de vistas En lugar de modificar las vistas existentes en su lugar (sobrescribiéndolas), Odoo proporciona una herencia de vistas en la que las vistas de "extensión" de los hijos se aplican encima de las vistas de la raíz y pueden agregar o eliminar en la que las vistas de "extensión" de los hijos se aplican encima de las vistas de la raíz y pueden agregar o eliminar contenido de sus padres.

contenido de sus padres.

Una vista de extensión hace referencia a su matriz usando el campo

Una vista de extensión hace referencia a su matriz usando el campo inherit_idinherit_id, y en lugar de una sola vista su, y en lugar de una sola vista su campo

campoarcharch se compone de cualquier número de elementos se compone de cualquier número de elementos xpathxpath de selección y alterar el co de selección y alterar el co ntenido de su vistantenido de su vista padre:

padre:

<!

<! — —lista de categorias de ideas mejoradas -->lista de categorias de ideas mejoradas -->

<record

<record id=id="idea_category_list2""idea_category_list2" model=model="ir.ui.view""ir.ui.view">>

<field

<field name=name="name""name">>id.category.list2id.category.list2</field></field>

<field

<field name=name="model""model">>idea.categoryidea.category</field></field>

<field

<field name=name="inherit_id""inherit_id" ref=ref="id_category_list""id_category_list"/>/>

<field

<field name=name="arch""arch" type=type="xml""xml">>

<!-- Encontrar la descripción del campo y agregar el campo

<!-- Encontrar la descripción del campo y agregar el campo

Idea_ids después de ella -->

Idea_ids después de ella -->

<xpath

<xpath expr=expr="//field[@name='description']""//field[@name='description']" position=position="after""after">>

<field

<field name=name="idea_ids""idea_ids" string=string="Number of ideas""Number of ideas"/>/>

</xpath> </xpath> </field> </field> </record> </record> expr expr Un

Un XPath XPath expresión seleccionar un solo elemento en la vista padre. Genera un error si coincide con ningúnexpresión seleccionar un solo elemento en la vista padre. Genera un error si coincide con ningún elemento o más de uno

elemento o más de uno

position position

Operación que se aplicará al elemento coincidente: Operación que se aplicará al elemento coincidente:

inside inside

 Añade el cuerpo de

(14)

replace replace

Sustituye el elemento emparejaron con el cuerpo de

Sustituye el elemento emparejaron con el cuerpo de xpathxpath, en sustitución de cualquier, en sustitución de cualquier $0$0ocurrencia nodo enocurrencia nodo en el nuevo cuerpo con el elemento original,

el nuevo cuerpo con el elemento original,

before before

Inserta el cuerpo

Inserta el cuerpo xpathxpath como un hermano antes del elemento emparejado como un hermano antes del elemento emparejado

after after

Inserta el cuerpo

Inserta el cuerpo xpathxpath como un hermano después del elemento emparejado como un hermano después del elemento emparejado

attributes attributes

 Altera los atributos del elemento emparejado usando elementos espec

 Altera los atributos del elemento emparejado usando elementos espec ialesialesattributeattribute en el cuerpo de en el cuerpo de xpathxpath Tip

Tip

Cuando búsqueda de un solo elemento, el atributo

Cuando búsqueda de un solo elemento, el atributo positionposition se puede establecer directamente sobre el elemento se puede establecer directamente sobre el elemento que se encuentran. Ambas herencias a continuación le dará el mismo resultado.

que se encuentran. Ambas herencias a continuación le dará el mismo resultado.

<xpath

<xpath expr=expr="//field[@name='description']""//field[@name='description']" position=position="after""after">>

<field

<field name=name="idea_ids""idea_ids" />/>

</xpath>

</xpath>

<field

<field name=name="description""description" position=position="after""after">>

<field

<field name=name="idea_ids""idea_ids" />/>

</field>

</field>

Ejercicio Ejercicio

 Alterar el contenido existente  Alterar el contenido existente

Utilizando el modelo de herencia, modificar el vigente

Utilizando el modelo de herencia, modificar el vigente sociosocio modelo para añadir un campo booleano modelo para añadir un campo booleano instructor instructor  , y un , y un campo Many2Many que corresponde a la relación de sesión - socio

campo Many2Many que corresponde a la relación de sesión - socio

Usar la vista de la herencia, Muestra este campos en la vista formulario de empresa Usar la vista de la herencia, Muestra este campos en la vista formulario de empresa

Nota Nota

Esta es la oportunidad para introducir el modo de desarrollador para inspeccionar la vista, encontrará su ID externo y Esta es la oportunidad para introducir el modo de desarrollador para inspeccionar la vista, encontrará su ID externo y el lugar para poner el nuevo campo.

el lugar para poner el nuevo campo. 1.

1. Crear Crear un un archivoarchivo openacademy/models/partner.pyopenacademy/models/partner.pye importarlo ene importarlo en __init__.py __init__.py

2.

2. Crear Crear un un archivoarchivo openacademy/views/partner.xmlopenacademy/views/partner.xmly añadirlo ay añadirlo a __manifest__.py __manifest__.py

openacademy/__init__.py 

openacademy/__init__.py 

# coding: utf-8

# coding: utf-8

-*-from

from .. importimport controllerscontrollers from

from .. importimport modelsmodels from

from .. importimport partnerpartner

openacademy/__manifest__.py 

openacademy/__manifest__.py 

# 'security/ir.model.access.csv', # 'security/ir.model.access.csv', 'templates.xml' 'templates.xml',, 'views/openacademy.xml' 'views/openacademy.xml',, 'views/partner.xml' 'views/partner.xml',, ], ], # only loaded

# only loaded in demonstration modein demonstration mode

'demo' 'demo':: [[

openacademy/partner.py 

openacademy/partner.py 

# coding: utf-8 # coding: utf-8 -*-from

from odooodoo importimport fields,fields, modelsmodels class

class PartnerPartner(models(models..Model):Model): _inherit

_inherit == 'res.partner''res.partner'

# Agreggue una columna nueva

# Agreggue una columna nueva al modelo res.partner, por defecto los al modelo res.partner, por defecto los partners no sonpartners no son

#

# instructorinstructoreses

instructor

instructor == fieldsfields..Boolean(Boolean("Instructor""Instructor",, defaultdefault==False)False) session_ids

session_ids == fieldsfields..Many2many(Many2many('openacademy.session''openacademy.session',, string

string=="Attended Sessions""Attended Sessions",, readonlyreadonly==True)True)

openacademy/views/partner.xml 

openacademy/views/partner.xml 

<?xml version="1.0" encoding="UTF-8"?>

(15)

<odoo> <odoo>

<data> <data>

<!-- Add instructor field to existing view

<!-- Add instructor field to existing view -->-->

<record

<record model=model="ir.ui.view""ir.ui.view" id=id="partner_instructor_form_view""partner_instructor_form_view" >> <field

<field name=name="name""name">>partner.instructorpartner.instructor</field></field> <field

<field name=name="model""model">>res.partnerres.partner</field></field> <field

<field name=name="inherit_id""inherit_id" ref=ref="base.view_partner_form""base.view_partner_form"/>/> <field

<field name=name="arch""arch" type=type="xml""xml">> <notebook

<notebook position=position="inside""inside">> <page

<page string=string="Sessions""Sessions">> <group>

<group> <field

<field name=name="instructor""instructor"/>/> <field

<field name=name="session_ids""session_ids"/>/> </group> </group> </page> </page> </notebook> </notebook> </field> </field> </record> </record> <record

<record model=model="ir.actions.act_window""ir.actions.act_window" id=id="contact_list_action""contact_list_action">> <field

<field name=name="name""name">>ContactsContacts</field></field> <field

<field name=name="res_model""res_model">>res.partnerres.partner</field></field> <field

<field name=name="view_mode""view_mode">>tree,formtree,form</field></field> </record>

</record> <menuitem

<menuitem id=id="configuration_menu""configuration_menu" name=name="Configuration""Configuration"

parent=

parent="main_openacademy_menu""main_openacademy_menu"/>/> <menuitem

<menuitem id=id="contact_menu""contact_menu" name=name="Contacts""Contacts"

parent=

parent="configuration_menu""configuration_menu"

action=

action="contact_list_action""contact_list_action"/>/> </data> </data> </odoo> </odoo>

Domains

Domains

En Odoo,

En Odoo,

dominios

dominios

son valores que codifican las condiciones en registros. Un dominio es

son valores que codifican las condiciones en registros. Un dominio es

una lista de

una lista de

los criterios utilizados para seleccionar un subconjunto de los registros de un m

los criterios utilizados para seleccionar un subconjunto de los registros de un m

odelo. Cada criterio es

odelo. Cada criterio es

un triplete, con un nombre de campo,

un triplete, con un nombre de campo,

un operador y un valor.

un operador y un valor.

Por ejemplo, cuando se utiliza en el

Por ejemplo, cuando se utiliza en el

 producto

 producto

 modelo de dominio de la

 modelo de dominio de la

siguiente selecciona todos

siguiente selecciona todos

los

los

servicios

servicios

 con un precio unitario mayor a

 con un precio unitario mayor a

1000

1000

:

:

[(

[('product_type''product_type',, '=''=',, 'service''service'),), (('unit_price''unit_price',, '>''>',, 10001000)])]

Por criterios predeterminados se combinan con un AND implícito.

Por criterios predeterminados se combinan con un AND implícito.

Los operadores lógicos

Los operadores lógicos

& & 

(Y),

(Y),

||

(OR)

(OR)

y

y

!!

(NO) se pueden utilizar para combinar explícitamente crit

(NO) se pueden utilizar para combinar explícitamente crit

erios. Se utilizan en posición prefijo (el

erios. Se utilizan en posición prefijo (el

operador se inserta antes de que sus argumentos en lugar de entre).

operador se inserta antes de que sus argumentos en lugar de entre).

Por ejemplo para seleccionar los

Por ejemplo para seleccionar los

productos "que son servicios de

productos "que son servicios de

O

O

 tienen un precio unitario que es

 tienen un precio unitario que es

NO

NO

 entre 1000 y 2000":

 entre 1000 y 2000":

[

['|''|',,

(

('product_type''product_type',, '=''=',, 'service''service'),),

'!' '!',, '&''&',, ( ('unit_price''unit_price',, '>=''>=',, 10001000),), ( ('unit_price''unit_price',, '<''<',, 20002000)])]

Un parametro

Un parametro

domaindomain

 puede ser añadido a los campos relacionales para limitar

 puede ser añadido a los campos relacionales para limitar

los registros válidos

los registros válidos

para la relación cuando se trata de seleccionar registros en la

para la relación cuando se trata de seleccionar registros en la

interfaz del cliente.

interfaz del cliente.

Ejercicio

Ejercicio

Dominios en los campos relacionales

Dominios en los campos relacionales

Al seleccionar el instructor para una

Al seleccionar el instructor para una

sesión

sesión

 , sólo los instructores (socios con

 , sólo los instructores (socios con

instructorinstructor

conjunto

conjunto

a

a

TrueTrue

) deben ser visibles.

) deben ser visibles.

openacademy/models.py 

openacademy/models.py 

duration

Referencias

Documento similar

El útil de más empleo, tanto para podar co- mo para cortar esquejes y demás necesario pa- ra injertar, es la tijera de fiodar (fig.. Conviene tener una gran- de, de 2o a 25

No entanto, em rigor, a lei inconstitucional (menos favorável), por não ser válida, não consta de uma verdadeira sucessão de leis penais, e, por isso a protecção do caso

- Fase Visual: Color rojo cereza. Puede presentar un pequeño precipitado de sales tartáricas o de polifenoles polimerizados. - Fase Olfativa: Aroma limpio y complejo, donde destaca

Si introducir = FALSE (por defecto), el usuario debe indicar el conjunto de datos que desea analizar usando los argumentos x y/o variable.. Si introducir = TRUE, se le solicitará

Un predictor ocupando su tiempo haciendo la diagnosis meteorológica está más en consonancia con su trabajo, entendiendo qué y por qué existen ciertas estructuras atmosféricas,

Debido a la calidad y el legado de nuestra compañía, los cuales se reflejan en nuestros pianos, elegir un instrumento hecho por Steinway &amp; Sons tiende a ser una decisión

1. LAS GARANTÍAS CONSTITUCIONALES.—2. C) La reforma constitucional de 1994. D) Las tres etapas del amparo argentino. F) Las vías previas al amparo. H) La acción es judicial en

De la intersección de la líneas de acción de esta fuerzas se construye el polígono de fuerzas que nos dará la línea de empujes correspondiente a las posiciones de E y R