Traduccion Openerp
Traduccion Openerp
Recetario
Holger Brunn
Alexandre Fayolle
Daniel Reis
BIRMINGHAM - MUMBAI
Odoo Recetario de desarrollo
Copyright © 2016 Packt Publishing
Todos los derechos reservaron. Ninguna parte de este libro puede ser reproducida,
almacenado en un retrieval sistema, o transmitido en cualquier forma o por cualquier medio,
sin el permiso escrito previo del editor, exceptúa en el caso de menciones breves embedded
en críticos unrticles o revisiones.
Cada esfuerzo ha sido hecho en la preparación de este libro para asegurar la exactitud de la
información presentó. Aun así, la información contenida en este libro está vendido sin
garantía, tampoco expresar o implicó. Tampoco los autores, no Packt Publicando, y sus
comerciantes y los distribuidores serán aguantados propensos para cualesquier daños
causados o alegados para ser causados directamente o indirectamente por este libro.
Packt La editorial ha intentado para proporcionar información de marca aproximadamente
todo de las compañías y products mencionó en este libro por el uso apropiado de capitales.
Aun así, Packt Publicando no puede garantizar la exactitud de esta información.
ISBN 978-1-78588-364-4
www.packtpub.com
FM-2
Crédito
s
Autores Coordinador de
Holger Brunn proyecto
Kinjal Bari
Alexandre Fayolle
Daniel Reis
Proofreader
Safis Editando
Reviewers
Guewen Baconnier
Indexer
Stefan Rijnhart Monica Ajmera Mehta
Editores técnicos
Menza Mathew
Deepti Tuscano
Editores de copia
Merilyn Pereira
Alfa Singh
FM-3
Sobre los Autores
Holger Brunn Ha sido un código abierto ferviente defiende desde entonces entre para
contactar con el mercado de código abierto sometime en el nineties. Con un fondo
académico en filosofía y sociología, gire su interés a lógica generalizada, el cual prueba útil
en muchos aspectos de su trabaje. Convirtiendo en un programador profesional era un
efecto de lado de su hobbyist interest, combinado con una parte-trabajo de tiempo con un
muy abierto-mentor importado a quien debe mucho agradecimiento.
Ha programado para ERP y sistemas similares en posiciones diferentes desde entonces
2001. Para los últimos ocho años, ha dedicado su tiempo a TinyERP, el cual servino
OpenERP y evolucionado a Odoo. Actualmente, trabaja en Therp BV en el Netherlands como
desarrollador y es un miembro activo del Odoo Asociación Comunitaria (OCA). Es más
interesado en trabajo fundamental en módulos técnicos, pero también disfruta contributing a
otros proyectos, con un foco en UI y sitio web widgets, CRM, y administración de
conocimiento.
Alexandre Fayolle empezó trabajar con Linux y software libre en el mid 1990s y deprisa
se interesó en el lenguaje de programación de Pitón. Entre 1999 y 2012, ayude dirigir
Logilab, una compañía él cofounded, especialice en desarrollo de Pitón, y tuvo la
oportunidad de trabajar en proyectos para compañías grandes como EDF, Arcelor-Mittal, y
GdF Suez (ahora Engie) utilizando el Cubicweb marco.
Él también los proyectos divertidos emprendidos que implican aprendizaje de máquina,
procesamiento de lengua natural, y multi-sistemas de agente. En 2012, una Camptocamp
para compartir su pericia encima Pitón, PostgreSQL, y Linux con el equipo que implementa
Odoo (OpenERP en el tiempo). Él currently dirige proyectos para Camptocamp y es
fuertemente implicado en el Odoo Asociación Comunitaria. En su tiempo de sobra, le gusta
jugar el vibraphone en un cuarteto de jazz, pero recientemente ha sido sabido para escribir
un libro sobre Odoo, el cual espera que disfrutarás.
FM-4
Daniel Reis ha sido trabajando en el LO industria para encima 15 años en desarrollador,
asesor, y funciones de administración. La mayoría de este trabajo era en el Capgemini empresa
de asesoría de la multinacional, implementando soluciones empresariales propietarias para
reference compañías en una variedad de sectores, como industria, telecomunicaciones, y
amontonando. Daniel tiene un BSc en la matemática aplicada y un maestro es en
administración empresarial del ISCTE Escuela Empresarial.
Está trabajado con Odoo soluciones (anteriormente OpenERP) since 2010, y es un colaborador
activo en el Odoo proyectos de asociación comunitaria. Ha sido un hablante en el Abierto
Días conferencia anual y otros acontecimientos de código abierto. Es el autor del
primer Odoo libro de desarrollo: Odoo Desarrollo Essentials, también por Packt
Publicando.
Él actualmente trabajos en Securitas, la compañía de servicios de seguridad
global, donde ha introducido Pitón, Odoo, y otras soluciones de código abierto a la
compañía es carpeta de aplicaciones.
Doy las gracias a mi mujer, Maria José, para todoth e soporte y paciencia
que hizo este libro posible.
FM-5
Sobre el Reviewers
Guewen Baconnier Es un tipo discreto que no disfruta siendo puesto adelante. Trabaja en
Camptocamp donde está sido un TinyERP programamer antes de emotivo a OpenERP y ahora
Odoo. Es un entusiasta de software libre y un miembro activo del Odoo Asociación
Comunitaria (OCA), donde sus responsabilidades implican, entre otros, siendo el desarrollador
de ventaja del OCA Marco de Conector. Guewen También encanta libros así que tener que le
encuentras,
Hay una posibilidad buena pueda tener su nariz en uno, tampoco leyendo un libro técnico para
mantener arriba con su curiosidad ilimitada y hambre para aprender, o leyendo un novel a viaje en
algún fictional universo, o whatever el bien lee cayó a sus manos. Le gusta ir de excursión en el
campo con su mujer amada. Es también el padre feliz de dos niños buenos, con quien disfruta
gastar tiempo, paseando, yendo a la biblioteca, leyendo libros, y jugando Kerbal Programa
Espacial.
Me gustaría dar las gracias a mi mujer y niños para de apoyo mío tiredness
en el morrows de anocheceres largos de revisar. Y me gustaría dar las gracias
a Alexandre Fayolle quién me ayudé forma esta biografía corta. Finalmente,
gracias a mis colegas y a todo contributors del OCA de quien aprendo todos
los días.
Stefan Rijnhart es una vida-el código abierto largo defiende y ha sido un tiempo lleno
Odoo asesor y desarrollador desde entonces 2010. Disfruta colaborar en el Odoo
Comunidad
Asociación (OCA), el cual encuentra para ser mutuamente beneficioso a sus clientes'
proyectos. En el
OCA, Stefan jugó una función clave en la creación del OpenUpgrade proyecto de migración
para Odoo y en el Odoo Comunitario Backports proyecto (OCB). Off-line, le puedes encontrar
montando una bicicleta cargadora through las calles de Amsterdam con su hijo en el asiento
de frente, o jugando música con su banda. Entra tacto con Stefan en
http://abridor.amsterdam.
FM-6
www.packtpub.com
https://www2.packtpub.com/books/subscription/packtlib
i
Mesa de Contenidos
Capítulo 4: Modelos de Aplicación 63
Introducción 63
Definiendo la representación de Modelo y orden 64
Añadiendo campos de dato a un modelo 66
Utilizando un campo de flotador con configurable precisión 71
Añadiendo unmo netary campo a un Modelo 73
Añadiendo campos relacionales a un Modelo 74
Añadiendo una jerarquía a un Modelo 78
Añadiendo validaciones de constreñimiento a un Modelo 80
Añadiendo computó campos a un Modelo 82
Exponiendo Relacionó los campos almacenaron en otros modelos 85
Añadiendo dinámico relatlos iones que utilizan campos de Referencia 86
Añadiendo características a un Modelo que utiliza herencia 87
Utilizando Modelos Abstractos para características de Modelo
reutilizable 89
Utilizando herencia de Delegación para copiar características a otro
Modelo 91
Capítulo 5: Desarrollo de Lado de Servidor Básico 95
Introduction 95
Definiendo métodos de modelo y utilizar el API decorators 96
Informando errores al usuario 99
Obteniendo un vacío recordset para un modelo diferente 101
Creando registros nuevos 102
Actualizando valores de recordset registros 104
Buscando registros 107
Combinando recordsets 109
Filtrando recordsets 110
Traversing recordset Relaciones 112
Extendiendo la lógica empresarial definida en un Modelo 114
Extendiendo escribe() y crear() 117
Personalizando cómo los registros están buscados 120
Capítulo 6: Desarrollo de Lado de Servidor Adelantado
Techniques 125
Introducción 125
Cambio el usuario que actúa una acción 126
Llamada un método con un contexto modificado 128
Ejecuta consultas de SQL crudo 130
Escribir un brujo para guiar el usuario 133
Define onchange métodos 138
Llamada onchange métodos en el lado de servidor 141
Portuario viejo API código al nuevo API 143
ii
Mesa de
Contenidos
Capítulo 7: Depuración y Testaje Automatizado 153
Introducción 153
Produciendo registros de servidor para ayudar depurar métodos 153
Utilizando el Odoo concha a interactivamente métodos de
llamada 157
Utilizando el depurador de Pitón para localizar ejecución de
método 159
Escribiendo pruebas para vuestro módulo que utiliza YAML 164
Escribiendo pruebas para vuestro módulo que utiliza pruebas de
unidad de la Pitón 168
Corriendo pruebas de servidor 172
Utilizando el Odoo Asociación Comunitaria maintainer quality
herramientas 173
Capítulo 8: Backend Vistas 179
Introducción 180
Añadiendo un elemento de carta y acción de ventana 180
Teniendo una acción abre una vista concreta 184
Añadiendo contenido y widgets a una vista de forma 186
Añadiendo botones a formas 189
Pasando parámetros a formas y acciones: Contexto 190
Definiendo filtros oficialmente listas: Ámbito 193
Vistas de lista 196
Vistas de búsqueda 198
Cambiando existiendo vistas: herencia de Vista 201
Documento-formas de estilo 205
Elementos de forma dinámica que utilizan attrs 207
Embedded Vistas 207
Kanban Vistas 209
Espectáculo kanban tarjetas en columnas según su estado 211
Vistas de calendario 212
Graph Y vistas de pivote 213
QWeb Informes 215
Capítulo 9: Dato de Módulo 219
Introducción 219
Utilizando externo IDs y namespaces 219
Cargando data utilizando XML archivos 221
Utilizando el noupdate y forcecreate banderas 224
Cargando el dato que utiliza CSV archivos 226
Cargando el dato que utiliza YAML archivos 228
Addon Actualizaciones y migración de dato 229
Capítulo 10: Seguridad de Acceso 233
Crea grupos de seguridad y asignarles a usuarios 233
Añade acceso de seguridad a modelos 238
iii
Mesa de
Contenidos
Acceso de límite a campos en modelos 241
Límite el acceso récord que utiliza reglas récord 243
Utilizando grupo de seguridad para activar características 246
Capítulo 11: Internationalizatión 253
Instalando una lengua y configurar preferencias de usuario 253
Configura lengua-relacionó encuadres 257
Traduce textos a través de la interfaz de usuario de cliente de
web 258
Cuerdas de traducción exportadora a un archivo 261
Uso gettext herramientas para aliviar traducciones 264
Archivos de traducción de la importación 266
Capítulo 12: Automatización y Workflows 269
Introducción 269
Utilizando Kanban etapas y características 270
Creando acciones de servidor 273
Añadiendo messaging y siguiendo características 276
Utilizando acciones de servidor de código de Pitón 281
Utilizando automatizado unctions puntualmente condiciones 283
Utilizando automatizó acciones encima condiciones de
acontecimiento 288
Inspeccionando construido-en workflows 291
Capítulo 13: Desarrollo de Servidor de la Web 295
Introducción 295
Marca un camino accesible de la red 295
Restringe acceso a web camino accesibles 300
Consume los parámetros pasaron a vuestro handlers 302
Modificar un existiendo handler 304
Utilizando el RPC API 307
Capítulo 14: Desarrollo de Sitio web del CMS 311
Introducción 311
Extendiendo CSS y Javascript para el sitio web 311
Creando o modificando plantillas - QWeb 314
Ofreciendo fragmento al usuario 318
Capítulo 15: Desarrollo de Cliente de la Web 325
Introducción 325
Creando hecho de encargo widgets 325
Utilizando cliente-lado QWeb plantillas 331
Haciendo RPC llamadas al servidor 333
Escribiendo pruebas para código de lado del cliente 336
Depurándoter código de lado del cliente 340
iv
Mesa de
Contenidos
Capítulo 16: Despliegue de Servidor 345
Introducción 345
Instalando Odoo para producción 345
Adaptando el archivo de configuración para producción 351
Instalado Odoo como servicio de sistema 355
Configure Un inverso proxy y SSL 357
Uso buildout para repeatable complexiones 362
Índice 371
v
Prefacio
Odoo, anteriormente sabido cuando OpenERP, es una plataforma grande para
desarrolladores. El marco en su core es muy rico y deja construir cliente–aplicaciones de
servidor de tachar así como adaptando existiendo aplicaciones a vuestras necesidades a
través de un mecanismo de extensión listo y un diseño muy modular. Las versiones más
tardías han traído una riqueza de nuevo possibilities con la adición de un lleno-desarrollo
de sitio web presentado stack. El alcance es enorme y es fácil para recién llegados para
sentir perdidos.
Para años, Odoo los desarrolladores han sido aprendiendo su oficio por leer el código del addon
módulos, los cuales están construidos arriba de the marco para proporcionar características de
administración de la empresa.
Mientras eficaz, el proceso es mucho tiempo y error prone, desde entonces es difícil de saber si el
código de fuente estás aprendiendo de está utilizando las posibilidades más tardías ofrecieron por
el marco, o si estás mirando en un módulo más viejo aquello no ha sido actualizado para utilizar
estas características. Para hacer las cosas peores, algunos flujos de código son intrínsecamente
duros de seguir porque son en parte en la capa de lógica empresarial, en parte en la capa de base
de datos, en parte en la petición handling capa, y en parte en el código de lado del cliente. La
introducción de un nuevo API en versión 8 tiene hizo cosas aún más confundiendo, desde entonces
la mayoría de la base de código no fue inmediatamente ported a este nuevo API.
Este libro está significado para salvarte tiempo por tocar en a los años de experimentar
acumulado por largo-cronometrar Odoo colaboradores para aprender las buenas prácticas
actuales en Odoo desarrollo por centrar en las características nuevas de versión 9, y también
dando una base sólida en el existiendo funcionalidad madura del marco. Since Odoo Tiene una
tradición larga de garantizar backward compatibilidad, la mayoría del material presentado tiene
que todavía trabajo con el upcoming versiones.
vii
Prefacio
viii
Prefacio
Este foco de libro encima desarrollo de aplicación del núcleo. No cubre cómo para utilizar el
business las aplicaciones proporcionadas por Odoo. Puedes querer referir a Trabajar con
Odoo, por Greg Musgo, para este.
Este libro no proporciona explicaciones aproximadamente cómo el internals del trabajo de
aplicaciones de administración de empresa. Para entender esto, tendrás que leer el código
de fuente y experimento para tú. Siendo familiar con los contenidos del Odoo Recetario de
Desarrollo tendría que hacer vuestra vida más fácil, cuando contiene punteros a partes del
código puedes leer para aprender sobre un tema concreto.
Siy nuestro workstation está corriendo Windows o MacOS, te aconsejáis para instalar un Debian
máquina virtual para trabajar con Odoo. Mientras es posible de desarrollar natively encima
Windows o Mac, habiendo un entorno de desarrollo como cercano como posible al entorno de
despliegue es una manera buena de evitar sorpresas malas y GNU/Linux es la plataforma de
despliegue recomendable para Odoo.
ix
Prefacio
Es allí un Entorno de Desarrollo Integrado recomendable (IDE) para Odoo? Esto es una
cuestión frecuentemente preguntada por recién llegados. La respuesta mejor es para
utilizar cualquier herramienta eres familiar con. Las elecciones populares incluyen Eclipse
o PyCharm, pero un número muy alto de experimented desarrolladores, incluyendo el
núcleo Odoo desarrolladores, uso justo un editor de texto de la programación como vim,
GNU emacs, or Texto Sublime para tener la sintaxis que destaca y útil helpers como sangría
automática, mientras utilizando el depurador de Pitón para depurar. Está recomendado
para empezar las herramientas básicas porque IDEs tener una tendencia para esconder
complejidad tendrías que ser familiar con para fijar los problemas más duros.
Secciones
En este libro, encontrarás muchos headings aquello aparece frecuentemente (Preparándose,
Cómo para hacerlo,
Cómo trabaja, Allí ha más, y Ver también).
Para dar instrucciones claras encima cómo para completar una receta, utilizamos estas
secciones como sigue:
Preparándose
Esta sección te dices qué para esperar en la receta, y describe cómo para instalar cualquier
software o cualesquier encuadres preliminares requirieron para la receta.
Cómo trabaja…
Esta sección normalmente consta de una explicación detallada de qué pasado en la sección
anterior.
Allí ha más…
Esta sección consta de información adicional sobre la receta para hacer el lector más
sabeledgeable sobre la receta.
Ve también
Esta sección proporciona enlaces útiles a otra información útil para la receta.
x
Prefacio
Convenciones
En este libro, encontrarás un número de estilos de texto que distingue entre clases diferentes
of información. Aquí es algunos ejemplos de estos estilos y una explicación de su significado.
Palabras de código en texto, nombres de mesa de la base de datos, nombres de carpeta,
filenames, extensiones de archivo, pathnames, dummy URLs, entrada de usuario, y mangos
de Twitter están mostrados como sigue: "The parsing del archivo de configuración por Odoo
está hecho utilizando la Pitón ConfigParser módulo."
Un bloque de código está puesto como sigue:
[DEFAULT]
Casa = /de
proyecto/odoo/proyecta/proyecto1 env =
dev
Prefijo = %(proyecto)s/%(env)s
[Opciones]
addons-Camino =
%(prefijo)s/odoo/addons,%(prefijo)s/OCA/servidor-dato de
herramientas_dir = %(prefijo)s/dato_dir
Cuándo deseamos dibujar vuestra atención a una parte particular de un bloque de código,
las líneas pertinentes o los elementos están puestos en negrita:
{ 'Nombre': 'Capítulo 03 código',
'Depende': ['base', 'decimal_precision],
'Dato': ['libro/de biblioteca_de las vistas.xml'] }
Los plazos nuevos y las palabras importantes están mostrados en negrita. Palabras que
ves en la pantalla, por ejemplo, en cartas o cajas de diálogo, aparece en el texto así: "Clic
en el Dirigir enlace de Bases de datos."
Retroalimentación de lector
Feedback De nuestros lectores es siempre bienvenidos. Dejado nos saber qué piensas
sobre este reservar— qué te gustó o desagradó. Retroalimentación de lector es importante
para nosotros tan nos ayudo desarrollar títulos que te realmente conseguirá el más fuera
de.
Para enviarnos retroalimentación general, simemail de chapa
[email protected], y mencionar el título del libro en el tema de vuestro
mensaje.
Si hay un tema que tienes pericia en y estás interesado en cualquier escritura o
contribuyendo a un libro, ver nuestra guía de autor en
www.packtpub.com/authors.
Soporte de cliente
Ahora que eres el dueño orgulloso de un Packt libro, tenemos un número de cosas para
ayudarte para conseguir el más de vuestra compra.
1. Registro en o registro a nuestro sitio web que utiliza vuestra dirección de email y
password.
2. Cercar el puntero de ratón en el tabulador de SOPORTE en la parte superior.
3. Clic encima Descargas de Código & Errata.
4. Introducir el nombre del libro en la caja de Búsqueda.
5. Seleccionar el libro para qué estás mirando para descargar los archivos de código.
6. Escoge de la gota-abajo carta donde you adquirió este libro de.
7. Clic encima Descarga de Código.
También puedes descargar los archivos de código por clicking en el botón de Archivos del
Código en la página web del libro en el Packt sitio web Editorial. Esta página puede ser accedida
por introducir el nombre del libro en la caja de Búsqueda. Complacer nota que necesitas ser
logged en a vuestro Packt cuenta.
xii
Prefacio
Una vez el archivo está descargado, complacer marca seguro que te unzip o extraer la
carpeta que utiliza la versión más tardía de:
f WinRAR / 7-Cremallera para
f Windows Zipeg / iZip /
f UnRarX para Mac 7-
Cremallera / PeaZip para
Linux
Errata
A pesar de que hemos tomado cada cuidado para asegurar la exactitud de nuestro contenido,
las equivocaciones pasan. Si encuentras una equivocación en uno de nuestros libros—quizás
una equivocación en el texto o el código— seríamos agradecidos si podrías informar esto a
nosotros. Por hacer tan, puedes salvar otros lectores de frustración y ayudarnos mejorar
versiones subsiguientes de este libro. Si encuentras cualquier errata, complacer informarles por
visitar http://www.packtpub.com/submit-errata, seleccionando vuestro libro, clicking en
el Errata enlace de Forma de la Sumisión, e introduciendo los detalles de vuestro errata. Una
vez vuestro errata está verificado, vuestra sumisión será aceptada y el errata
Ser cargado a nuestro sitio web o añadido a cualquier lista de existir errata bajo el Errata
sección de aquel título.
Para ver el anteriormente entregado errata, va a https://www.packtpub.com/books/
soporte/de contenido e introducir el nombre del libro en el campo de búsqueda. La
información requerida aparecerá bajo el Errata sección.
Piratería
Piratería de copyrighted el material en el Internet es un problema actual a través de todos
los medios de comunicación. En Packt, tomamos la protección de nuestro copyright y
autoriza muy seriamente. Si encuentras cualesquier copias ilegales de nuestros trabajos en
cualquier forma en el Internet, complacer proporcionarnos con la dirección de ubicación o
nombre de sitio web inmediatamente de modo que podemos perseguir un remedio.
Complacer contactarnos en [email protected] con un enlace al sospechó material
pirateado.
Apreciamos vuestra ayuda en proteger nuestros autores y nuestra capacidad de traerte contenido
valioso.
xiii
Prefacio
Cuestiones
Si tienes un problema con cualquier aspecto de este libro, nos puedes contactar
en [email protected], y haremos nuestro mejores de dirigir el
problema.
xiv
1
Instalando el
Odoo Desarrollo
Entorno
En este capítulo, cubriremos los temas siguientes:
Introducción
Hay muchas maneras de instalar un Odoo entorno de desarrollo. Este capítulo propone uno
de estos, a pesar de que ciertamente encontrarás un número de otro tutorials en la web que
explica otro approaches. Mantiene en importar que este capítulo es sobre un entorno de
desarrollo, el cual tiene requisitos diferentes de un entorno de producción, cubierto en
Capítulo 16, Despliegue de Servidor.
1
Instalando el Odoo Entorno de Desarrollo
Este libro supone estás corriendo Debian GNU/Linux como su versión estable (Jessie en el
tiempo de escribir). Ubuntu is Otra elección popular, y desde entonces está construido arriba
de Debian, la mayoría de los ejemplos en este libro tendrían que trabajar sin cambios.
Cualquier distribución de Linux escoges, tendrías que tener alguna idea de cómo para
utilizar él de la línea de orden, y teniendo unas cuantas ideas abfuera administración de
sistema ciertamente no causa cualquier daño.
Preparándose
Suponemos aquel Linux es arriba y corriendo y que tienes una cuenta con acceso de raíz,
tampoco porque sabes la contraseña de raíz o porque sudo ha sido configurado. En el
seguiring páginas, seremos utilizar $(whoami) siempre que el login de vuestro usuario de
trabajo está requerido en una línea de orden. Esto es una concha manda cuál sustituirá
vuestro login en la orden estás escribiendo.
Algunas operaciones sin duda serán más fáciles si tienes un GitHub
cuenta. Va a https://github.com y crear uno si no tienes uno ya.
Amonestación!
Esto es un paquete proporcionado por el Odoo maintainer para
Debian Jessie. Si estás utilizando otra distribución, explora a
http://descarga. gna.org/wkhtmltopdf/0.12/0.12.1/ Y
descargar el paquete para vuestro sistema operativo.
4. Configura PostgreSQL:
$ sudo -u postgres createuser --createdb $(whoami)
$ createdb $(whoami)
5. Configura git:
$ git config --Global user.name "Vuestro Nombre"
$ git config --Usuario global.Email [email protected]
3
Instalando el Odoo Entorno de Desarrollo
Puedes descargar los archivos de código del ejemplo para este libro de
vuestra cuenta en http://www.packtpub.com. Si adquiriste este
libro en otro lugar, puedes visitar
http://www.packtpub.com/support y registro para tener los
archivos e-mailed directamente a ti.
Puedes descargar los archivos de código por siguientes estos pasos:
fRegistro en o registro a nuestro sitio web que utiliza vuestra
dirección de email y contraseña
fCerca el puntero de ratón entabuladorde
WindowsfZipeg / iZip /
UnRarX para Macf7-
Cremallera / PeaZip para Linux
Cómo trabaja...
Las dependencias provienen varias fuentes. Primero, tienes las dependencias de núcleo
de Odoo, el Pythencima intérprete que suele corrido el código de fuente, y el PostgreSQL
servidor de base de datos utilizó para almacenar el dato de caso. Git Está utilizado para
código de fuente versioning y consiguiendo el código de fuente de Odoo él.
4
Capítulo 1
Desde entonces necesitaremos editar algunos archiva tan raíz o cuando postgres (el
PostgreSQL usuario administrativo) en nuestro servidor, necesitamos instalar una consola-
editor de texto basado. Sugerimos nano cuando es muy sencillo de utilizar, pero sentir libre
de escoger cualquier editor con qué sientes en aliviar mientras trabaja en la consola, como
vim, e3, o emacs-nox .
Wkhtmltopdf Es un runtime dependencia de Odoo utilizó para producir informes de PDF. La
versión requerida por Odoo 9.0 es 0.12.1, el cual no es incluido en actual GNU/distribuciones de
Linux. Afortunadamente para nosotros, el maintainers de wkhtmltopdf proporcionar prebuilt
paquetes para varias distribuciones en http://wkhtmltopdf.org/downloads.html (en la
sección de archivo). Aun así, Debian Jessie no es allí, así que el Odoo maintainers proporciona su
versión propia del
Paquete en http://nightly.odoo.com/extra/.
hay mucho otro runtime dependencias que es módulos de Pitón, el cual podemos instalar
utilizar pip en un entorno virtual. However, algunos de estos módulos de Pitón pueden
presentar algunas dependencias en nativos C bibliotecas para qué las encuadernaciones
de Pitón necesidad de ser compilada. Por tanto instalamos los paquetes de desarrollo para
estas C bibliotecas así como el paquete de desarrollo de la Pitón y un C compilador. Una
vez estas dependencias de complexión están instaladas, podemos utilizar pip -r
requisitos.txt (Un archivar cuál proviene el Odoo distribución de código de la fuente)
para descargar, compila, e instalar los módulos de Pitón.
Entornos virtuales
Pitón entornos virtuales, o virtualenv para cortos, es Pitón aislada workspaces. Son muy útiles a
desarrolladores de Pitón porque dejan diferentes workspaces con versiones diferentes de varias
bibliotecas de Pitón instaladas, posiblemente en versiones de intérprete de Pitón diferentes.
You Puede crear tan muchos entornos cuando deseas utilizar la orden virtualenv camino/
a/newenv. Esto creará un newenv directorio en la ubicación especificada, conteniendo un
Subdirectorio/ de cubo y un lib/pitón2.7 subdirectorio.
Hay dos maneras principales de utilizar un virtualenv. Lo puedes activar tan muestramos en
la receta
(Y llamada deactivate cuándo estás hecho) o puedes utilizar los guiones en el
directorio/ de cubo del entorno explícitamente por llamarles con su camino lleno, en qué
caso no necesitas para activar el virtualenv. Esto es principalmente un asunto de gusto,
así que tienes que experimento y descubrir which el estilo te convienes mejor para qué caso.
Puedes tener guiones de Pitón ejecutable con la primera línea que parece el siguiente:
#! /usr/Cubo/env pitón
Estos serán más fáciles de utilizar con un activados virtualenv. Esto es el caso con el
odoo.py guión, which te puede por tanto llamada en la manera siguiente:
$ ./odoo.py -d odoo-Prueba --addons-camino=addons --db-filtro=odoo-
probar$
PostgreSQL Configuración
En un GNU/sistema de Linux, Odoo trabaja muy bien con el default valores de
psycopg2 , el módulo de Pitón utilizó a access un PostgreSQL base de datos:
f Passwordless Autentificación si el usuario de base de datos tiene el mismo nombre
como el usuario actual en conexiones locales
f Usos de conexión local casquetes de ámbito
f del Unix El servidor de base de datos
escucha en portuario 5432
En aquel caso, there no tiene nada de particular para hacer: utilizamos el postgres
usuario administrativo para crear un usuario de base de datos qué participaciones
nuestro login nombre y darlo el correcto de crear bases de datos nuevas. Entonces
creamos una base de datos nueva con el mismo nombre como el usuario nuevo, el
cual será utilizado como default base de datos cuándo utilizando el psql orden.
Cuando en un servidor de desarrollo, es VALE para dar el PostgreSQL usuario más derechos
y para utilizar el --superuser orden-opción de línea más que justo --createdb. El efecto
neto es que este usuario puede entonces también create otros usuarios y globalmente
dirigir el caso de base de datos. Si sientes --superuser es demasiado, puedes todavía
quiere uso --createrole además de --createdb cuándo creando vuestro usuario de
base de datos. Evita hacer este encima servidores de producción cuando dé additional
apalancamiento a un atacante explotando una vulnerabilidad en alguna parte del código
desplegado (ve Capítulo 16, Despliegue de Servidor).
Si quieres utilizar un usuario de base de datos con un diferente login, necesitarás
proporcionar una contraseña para el usuario. Esto está hecho por pascantar el --
pwprompt bandera en la línea de orden cuándo creando el usuario, en qué caso la orden
incitará tú para la contraseña.
6
Capítulo 1
Si esta orden falla con un mensaje de error que dice que la base de datos
no existe, es porque no creaste una base de datos nombrada después de
vuestro login nombre en paso 3. Aquello es bien; justo añadir el --
dbname opción con una base de datos de existir nombre como --
dbname plantilla1.
Git Configuración
En algún punto en el libro, necesitarás utilizar git cometer. Esto fallará a no ser que algunos
la configuración básica está actuada; you necesidad de proporcionar Git con vuestro nombre
y dirección de correo electrónico. Git Te recordará para hacer este con un mensaje de error
bueno, pero puedes también él ahora.
Empezando el caso
Ahora viene elm oment has sido esperando a. Para empezar nuestro primer caso, primero
creamos una base de datos vacía nueva y entonces utilizar el odoo.py guión con la orden
siguiente-argumentos de línea:
f -d Nombre_de base de datos: Uso que base de datos por default.
7
Instalando elO doo Entorno de Desarrollo
hay más…
Yon la receta, descargamos la versión estable más tardía de Odoo utilizando la orden
siguiente:
Esto utiliza la rama oficial mantenida por Odoo. Uno emite con esta rama es que el bicho fija
contribuido por la comunidad no es siempre fusionado en una moda oportuna. El Odoo
Asociación Comunitaria (OCA) mantiene una rama paralela en qué fija y las mejoras son peer-
revisados por el comunitarios y tender para ser fusionado más rápido que en el oficial branch.
No es un tenedor de Odoo, y la versión más tardía de Odoo está fusionado atrás a aquella
rama diariamente.
Puedes querer utilizar él para vuestros desarrollos y despliegues, en qué caso necesitas
clonar Odoo así:
$ git Clon -b 9.0 --https de rama sola://github.com/oca/ocb.git odoo
8
Capítulo 1
Preparándose
Para esta receta necesitamos tener ya instalados Odoo. Suponemos que sea en
~/odoo-dev/odoo, y que el virtualenv está activado.
Esto significa que la orden siguiente exitosamente tendría que empezar un Odoo servidor:
$ ~/odoo-dev/odoo/odoo.py
Cómo trabaja...
El Odoo orden de inicio es un atajo para empezar un caso de servidor que utiliza el
directorio actual. El nombre de directorio es automáticamente utilizado como el nombre de
base de datos (para el -d opción), y el directorio actual es automáticamente añadido al
addons camino (el --addons-camino option) mientras contiene un Odoo addon módulo.
En la receta de preceder no verás el directorio actual en el addons camino porque no
contiene cualesquier módulos todavía.
9
Instalando el Odoo Entorno de Desarrollo
Allí ha más
Pordef ault el directorio actual está utilizado, pero el --opción de camino te dejas
para poner un camino concreto para utilizar en cambio. Por ejemplo, esto trabajaría de
cualquier directorio:
$ ~/odoo-dev/odoo/odoo.py Inicio --camino=~/odoo-dev/mi-odoo
La base de datos al uso también puede ser overridden utilizando el habitual -d opción. De
hecho, todo el otro habitual odoo.py orden-argumentos de línea, exceptúa --addons-
camino, trabajará. Por ejemplo, para poner el servidor que escucha puerto, uso la orden
siguiente:
$ ../odoo/odoo.py Inicio --xmlrpc-portuario=8080
Cuando podemos see, el Odoo orden de inicio puede ser una manera conveniente a
quickstart Odoo casos con su directorio de módulo propio.
Preparándose
Suponemos que vuestro entorno de trabajo está instalado y tienes un caso que corre. No
Lo empieza utilizando el odoo.py start manda mostrado en la receta anterior, cuando
configura el servidor con algunas opciones qué interferir con multi-administración de base
de datos.
1. Va all ogin pantalla de vuestro caso (si estás autenticado, registro fuera).
2. Clic en el Dirigir enlace de Bases de datos. Esto navigate a http://
localhost:8069/base de datos/de web/director (también puedes
señalar vuestro navegador directamente a aquel URL.).
10
Capítulo 1
11
Installing El Odoo Entorno de Desarrollo
Troubleshooting
Si estás redirigido a un login pantalla, esto es probablemente porque la
opción --db-el filtro estuvo pasado a Odoo y el nombre de base
de datos nuevo no emparejó el nombre de basede dato nuevo. Nota
que el odoo.py orden de inicio esto silenciosamente, haciendo sólo
la base de datos actual disponible. Para trabajar alrededor de este,
sencillamente retomar Odoo sin la orden de inicio, cuando mostrado en
la primera receta de este capítulo. Si tienes una configuración file (ve el
Almacenando la configuración de caso en una receta de archivo más
tarde en este capítulo), entonces comprueba que el db_opción de
filtro es unset o puesto a un valor que empareja el nombre de base de
datos nuevo.
2. Rellenar la forma:
Contraseña maestra: la contraseña maestra del Odoo el
servidor Nuevo Name: el nombre quieres dar a la copia
3. Clic en el Continuar botón.
4. Puedes entonces clic en el nombre de la base de datos nuevamente creada
en la pantalla de administración de la base de datos para acceder el login
pantalla para aquella base de datos.
14
Capítulo 1
2. Rellenar la forma:
Contraseña maestra: la contraseña maestra del Odoo servidor.
Formato de copia de seguridad: siempre cremallera de uso para una base de
datos de producción, cuando es el formato de copia de seguridad lleno real
único. Sólo utilizar el pg_formato de vertedero para una base de datos de
desarrollo donde tú no realmente cuidado sobre elf ile tienda (admin por
default).
2. Rellenar la forma:
Contraseña maestra: la contraseña maestra del Odoo servidor.
Archivo: un anteriorly descargó Odoo copia de seguridad.
Nombre de base de datos: proporcionar el nombre de la base de datos en
qué la copia de seguridad será restaurada. La base de datos no tiene que
existir en el servidor.
Generar una base de datos nueva uuid: deja unchecked si estás instalando
una base de datos cuál ha sido eliminado del servidor; otherwise
comprueba la caja. Hay poca diferencia entre ellos, y si en duda, dejándolo
unchecked es una elección segura.
3. Clic el Continuar botón.
Cómo trabaja...
Estas características, aparte del Cambio pantalla de contraseña maestra, corrido
postgresql órdenes de administración en el servidor e informe atrás a través de la
interfaz de web.
La contraseña maestra es una pieza muy importante de información qué vidas únicas en el
Odoo archivo de configuración del servidor y nunca es almacenado en la base de datos. Allí
utilizado para serun d efault valor de admin , pero utilizando este valor es una
responsabilidad de seguridad cuando es bien sabido. En Odoo v9, esto está identificado
como un "unset" la contraseña maestra y tú consiguen instados para cambiarlo cuándo
accediendo la interfaz de administración de la base de datos. Incluso si está almacenado
en el archivo de configuración bajo el admin_passwd entrada, esto no es igual como la
contraseña del admin usuario; estos son dos contraseñas independientes : la contraseña
maestra está puesta para un Odoo proceso de servidor, el cual él puede manejar casos de
base de datos múltiple, cada cual del cual tiene un independiente admin usuario con su
contraseña propia.
Para crear una base de datos nueva, Odoo utiliza el PostgreSQL createdb utilidad y llama
el interno Odoo función para inicializar la base de datos nueva en la misma manera cuando
cuando empiezas Odoo en una base de datos vacía.
Para duplicar una base de datos, Odoo utiliza el --opción de plantilla de createdb
pasando la base de datos original como un argumento. Esto esencialmente duplica la
estructura de la base de datos de plantilla en la base de datos nueva que utiliza interno y
optimizado PostgreSQL rutinas, el cual es mucho más rápido que creando una copia de
seguridad y restaurándolo (especialmente cuándo utilizando la webi nterface cuál requiere
descargar el archivo de copia de seguridad y cargándolo otra vez).
Copia de seguridad y restaurar las operaciones utilizan el pg_vertedero y pg_restaurar
utilidades respectivamente. Cuándo utilizando el .Formato de cremallera, la copia de
seguridad también incluirá una copia del archivo almacena qué contains una copia de los
documentos cuándo configuras Odoo a no mantener estos en la base de datos, el cual es el
default en 9.0. A no ser que lo configuras otherwise, estos archiva vivos en
~/.Participación/local/Odoo/filestore.
17
Instalando el Odoo Development Entorno
hay más...
Experimentado Odoo los desarrolladores generalmente no utilizan la interfaz de
administración de la base de datos, y actuar las operaciones de la línea de orden. Para
inicializar una base de datos nueva con demo dato para caso, el siguiente un-liner puede ser
utilizado:
$ createdb testdb && odoo.py -d testdb
La bonificación adicional de esta línea de orden es que puedes pedir instalación de addons
mientras eres en él utilizando para caso -i venta,compra,stock (más encima esto en
Capítulo 2,
Gestor Odoo Casos de Servidor).
Para duplicar una base de datos, parón el servidor, y correr la orden siguiente:
$ dropdb dbname
$ rm -rf ~/.Participación/local/Odoo/filestore/dbname
Para crear una copia de seguridad (suponiendo el PostgreSQL el servidor está corriendo
localmente), uso la orden siguiente:
$ pg_Vertedero -Fc -f dbname.Vertedero dbname
$ Alquitrán cjf dbname.tgz dbname.Vertedero
~/.Participación/local/Odoo/filestore/dbname
18
Capítulo 1
$ Alquitrán xf dbname.tgz
$ pg_Restaurar -C -d dbname dbname.Vertedero
Amonestación!
Si vuestro Odoo el caso utiliza un usuario diferente para conectar a la
base de datos you necesidad de pasar -U username de modo que
el usuario correcto es el dueño de la base de datos restaurada.
Puedes añadir opciones adicionales, y sus valores serán salvados en el archivo generado. Todo
el unset las opciones serán salvadas con su default conjunto de valor. Para conseguir una lista
de opciones posibles, uso:
$ odoo.py --Ayudar | menos
Esto proporcionará tú con alguna ayuda aproximadamente lo que las varias opciones
actúan. Para convertir de la forma de línea de la orden a la forma de configuración, uso el
nombre de opción largo, sacar el principal dashes, y convertir el dashes en el medio a
underscores: --sin-demo deviene sin_demo. Estos trabajos para más opciones, pero
hay unas cuantas excepciones listó en la sección próxima.
Editar el archivo myodoo.cfg (Uso la mesa en la sección siguiente para algunos parámetros
puedes querer cambio). Entonces para empezar el servidor con el salvó opciones, corridos la
orden siguiente:
$ odoo.py -c myodoo.cfg
Cómo trabaja...
En empezar arriba, Odoo carga su configuración en tres pases. Primero un conjunto de
default los valores para todas las opciones está inicializado del código de fuente. Entonces
la configuración es parsed, y cualquier valor definido en el archivo overrides el defaults.
Finalmente, la orden-opciones de línea están analizadas y sus valores override la
configuración obtenida del pase anterior.
Cuando mencionado más temprano, los nombres de las variables de configuración pueden
ser encontrados de los nombres de la orden-opciones de línea por sacar el principal dashes
unnd convirtiendo el medio dashes a underscores. Hay unas cuantas excepciones,
notablemente:
Aquí es una lista de las opciones generalmente puestas a través del archivo de configuración:
20
Capítulo 1
hay más...
El parsing del archivo de configuración por Odoo está hecho utilizando la Pitón
ConfigParser módulo. Este módulo apoya definir valores para variables de los valores de
otras variables que utilizan el %(sección.Variable)s notación. Puedes omitir sección
si el valor proviene la misma sección o si está definido en el especial [DEFAULT] sección.
Para caso, si quieres define la base de datos login para ser igual como el nombre de base
de datos, puedes escribir el siguiendo en vuestro Odoo archivo de configuración:
[Opciones]
db_Nombre = projectname
db_Usuario = %(options.db_nombre)s
21
Instalando el Odoo Entorno de Desarrollo
Un muy common el uso es para definir un prefijo común para los caminos del addons:
[DEFAULT]
Casa = /de
proyecto/odoo/proyecta/proyecto1 env =
dev
Prefijo = %(proyecto)s/%(env)s
[Opciones]
addons-Camino =
%(prefijo)s/odoo/addons,%(prefijo)s/OCA/servidor-dato de
herramientas_dir = %(prefijo)s/dato_dir
1. Conecta a vuestro caso y autenticar (no necesariamente tan admin; esta función es
disponible a todos los usuarios, pero el Administrador tiene más las herramientas
disponibles).
2. Clic en el abajo flecha luego a vuestro nombre de usuario en el superior correcto
corner de la página .
3. En la gota-abajo carta, clic encima Aproximadamente.
22
Capítulo 1
23
Instalando el Odoo Entorno de Desarrollo
5. Para salir modo de desarrollador, puedes editar el URL y sacar aquella cuerda, cierra
vuestro tabulador de navegador y abrir un nuevo un, o utilizar el Dejar Depurar opción de
Modo en el fondo del depurar gota-abajo carta luego a la carta de usuario en el derecho
superior de la pantalla.
Cómo trabaja...
Cuando en modo de desarrollador, tres cosas pasan:
Amonestación!
Prueba vuestro addons ambos con y sin modo de desarrollador,
cuando el unminified las versiones de las bibliotecas de
Javascript pueden esconder bichos qué mordisco único tú en el
minified versión.
24
Capítulo 1
Getting A punto
Parón cualquier caso actualmente corriendo con el Odoo fuente estás a punto de
actualización.
Marca una copia de seguridad de todas las bases de datos te preocupas aproximadamente
en caso algo va malo. Esto es evidentemente algo necesitas hacer para bases de datos de
producción. Ver el Managing Odoo receta de bases de datos del servidor para instrucciones.
Entonces hacer una nota de la versión actual de la fuente estás corriendo. La manera
mejor es para crear una etiqueta ligera que utiliza la orden siguiente:
$ cd ~/odoo-dev/odoo
$ git checkout 9.0
$ git Etiqueta 9.0-antes de que-actualización-$(fecha --iso)
Esto fetch la versión más tardía del código de fuente cometido a la rama actual.
Para actualizar un caso que corre en este código, corrido la orden siguiente:
3. Gota las bases de datos rotas y restaurarles de las copias de seguridad hiciste (ve el
Gestor Odoo receta de bases de datos del servidor para instrucciones).
4. Retomar vuestros casos y decir vuestros usuarios que elu pgrade ha sido aplazado.
Nota que en vida real, esto nunca tendría que pasar en una base de datos
de producción, porque habrías probado el upgrade por adelantado en una
copia de la base de datos, fijado los asuntos, y sólo hechos el upgrade en
el servidor de producción after haciendo seguro que corre perfectamente.
Pero a veces, todavía consigues sorpresas, tan incluso si eres realmente
seguro, marca una copia de seguridad.
Cómo trabaja...
Actualizando el código de fuente está hecho por hacer seguro somos en la rama correcta
que utiliza git checkout, y entonces fetching las revisiones nuevas que utilizan git
atracción. El --ff-la opción única causará un fracaso si tienes local comete no
presentar en el repositorio remoto. Si esto pasa y quieres mantener vuestros cambios,
puedes utilizar git atracción (sin --ff-único) para fusionar los cambios remotos con
el vuestro; otherwise, uso git reinicialización --origen duro/9.0 para forzar la
actualización, discarding vuestras modificaciones locales.
La orden de actualización utiliza las opciones siguientes:
f Actualiza la estructura de base de datos para los modelos definió en el module para
qué los cambios de estructura. Para actualizaciones en la rama estable de Odoo,
tendría que haber no tales cambios, pero esto puede pasar para vuestro propio
f addons o tercer partido addons.
Actualiza los registros de base de datos almacenaron en archivos de datos del
módulo, más notablemente tve. Él entonces recursively actualiza los módulos
instalados qué tiene declarado una dependencia en el módulo.
Desde el módulo de base es una dependencia implícita de todo Odoo módulos,
actualizándolo provocará una actualización de todos los módulos instalados en vuestro
instance. Para actualizar todos los módulos instalados, el alias todos pueden ser
utilizados en vez de base .
27
2
Gestor Odoo Servidor
Casos
En este capítulo, aprenderemos aproximadamente:
IntroductIón
En Capítulo 1, Instalando el Odoo Entorno de Desarrollo, hemos visto cómo para instalar un
Odoo el caso que utiliza sólo el núcleo "estándar" addons, los cuales están embarcados por el
editor. Este foco de capítulo encima añadiendo noncore addons a un Odoo caso, serlo túr propio
addons, o tercer-partido addons como los mantenidos por el Odoo Asociación Comunitaria
(OCA).
Preparándose
Esta receta supone tienes un caso a punto, con un archivo de configuración generó tan
descrito en Capítulo 1, Instalando el Odoo Entorno de Desarrollo. El código de fuente de
Odoo es disponible en ~/odoo-dev/odoo, y el archivo de configuración es en
~/odoo-dev/Mi-caso.cfg.
3. Modificar la línea por anexar una coma seguida por el nombre del directorio
quieres añadir al addons camino:
addons_Camino = ~/odoo-dev/odoo/openerp/addons,~/odoo-
dev/odoo/ addons,~/odoo-dev/local-addons
Puedes ordenado que línea un poco por añadir una variable de raíz y utilizándolo
para acortar la definición de camino (ve Capítulo 1, Instalando el Odoo
Development Entorno, para más en este):
Raíz = ~/odoo-dev
addons_Camino =
%(raíz)s/odoo/openerp/addons,%(raíz)s/odoo/
addons,%(raíz)s/local-addons
30
Capítulo 2
Cómo él works…
Cuándo Odoo está retomado, el archivo de configuración está leído. El valor del
addons_variable de camino está esperada para ser una coma-lista separada de directorios.
Los caminos relativos están aceptados, pero
Son relativos al directorio laborable actual, y por tanto tendría que ser evitado en el
archivo de configuración.
Al llegar a este punto, el nuevo addons presente en ~/odoo-dev/local-addons no es
disponible en la lista de disponible addon módulos del caso. Para este, necesitas actuar
una operación extra explicada en la receta próxima, Actualizando el addon lista de
módulos.
Allí ha más…
Cuándo llamas el odoo.py guión por primera vez para inicializar una base de datos nueva,
puedes pasar el --addons-argumento de línea de orden de camino con una coma-lista
separada de directorios. Esto initialize la lista de disponible addon módulos con todo el addons
encontrados en el suministrados addons camino. Cuándo tú esto, tienes que explícitamente
incluir la base addons directorio (odoo/openerp/addons) así como el núcleo addons directorio
(odoo/addons). Ser prudente—si pusiste un espacio después de las comas— necesitarás citar la
lista de directorios.
Puedes utilizar el --salvar opción a también salvar el camino al archivo de configuración:
$ odoo/odoo.py -d mydatabase \ --addons-
Camino="odoo/openerp/addons,odoo/addons,local-addons" \ --
salvar -c odoo-proyecto.cfg –Parón-después de que-init
En este caso, utilizando los caminos relativos es VALE, desde entonces serán convertidos
a caminos absolutos en el archivo de configuración.
Preparándose
Inicio túr caso, y conectar al caso que utiliza la cuenta de Administrador y activar el modo de
desarrollador (ve Capítulo 1, Instalando el Odoo Entorno de Desarrollo).
31
Dirige Odoo Casos de Servidor
32
Capítulo 2
Cómo trabaja…
Cuándo el botón de Actualización es clicked encima, Odoo leerá el addons variable de
configuración del camino, y para cada directorio en la lista, busque los subdirectorios inmediatos
que contienen un addon manifiesta archivo, el cual es un archivo nombró __openerp__.py,
almacenado en el addon directorio de módulo.
Odoo Lee el manifest esperando encontrar un diccionario de Pitón. A no ser que el
manifestar contiene un clave installable puesto a Falso , el addon módulo metadata
consta en la base de datos. Si el módulo era ya presente, la información está actualizada;
otherwise, un registro nuevo está creado. Si un anteriormente disponible addon el módulo
no es encontrado, el registro no es eliminado de la lista.
L /: Esto suele salvar vuestro caso-concreto addons cubo/:
o Esto incluye varios helper guiones de concha ejecutable
c filestore/: Esto está utilizado como tienda de archivo
a Registros/ (opcionales): Esto suele tienda los archivos
l de registro del servidor
33
Dirige Odoo Casos de Servidor
9. Crear un Git repositorio para este caso y añadir los archivos has añadido a
Git: $ git init
$ git Añade .
$ git Cometer -m "versión inicial de projectname"
34
Capítulo 2
Cómo trabaja…
Generamos una estructura de directorio limpia con claramente labeled directorios y dedicó
funciones. Especialmente, separamos el siguientes:
f El código mantenido por otras personas (en src/)
f El código concreto local
f El dato del caso
Por habiendo un virtualenv por proyecto, somos seguro que los proyectos' las
dependencias sonn ot yendo para interferir con las dependencias de otros proyectos que
puede ser correr una versión diferente de Odoo o utilizar tercio diferente-partido addon
módulos, los cuales necesitan versiones diferentes de dependencias de Pitón. Esto viene
en el coste de un poco espacio de disco.
En una manera similar, utilizando clones separados de Odoo y tercer-partido addon módulos para
nuestros proyectos diferentes, somos capaces de dejar cada cual de estos evolucionar
independientemente y sólo instalar actualizaciones en los casos que les necesita; de ahí,
reduciendo el riesgo de introducinregresiones de g.
El cubo/odoo el guión deja para correr el servidor sin teniendo que recordar los varios
caminos o activar el virtualenv. También pone el archivo de configuración para nosotros.
Puedes añadir guiones adicionales en allí para ayudar tú en vuestro día-a-trabajo de día, fo
caso, un guión para comprobar el tercio diferente-proyectos de partido que te necesidad de
correr vuestro caso.
Con respecto al archivo de configuración, sólo muestramos el bare opciones mínimas para
instalar aquí, pero evidentemente puedes poner más, como el nombre de base de datos,
the filtro de base de datos, o el puerto en qué el proyecto escucha. Complacer referir a
Capítulo 1, Instalando el Odoo Entorno de Desarrollo, para más información en este tema.
Finalmente, por gestor todo esto en un Git repositorio, deviene bastante fácil a replicate el
setup en un ordenador diferente y compartir el desarrollo entre un equipo.
Speedup Consejo
Para aliviar creación de proyecto, puedes crear un repositorio de
plantilla que contiene la estructura vacía, y tenedor que repositorio para
cada proyecto nuevo; esto salvará tú de retyping el cubo/odoo guión y
el .gitignore Archivo, y cualquiera otro archivo de plantilla
necesitas (configuración de integración continua, Readme.md,
ChangeLog, y tan encima).
Ve también
Si tú así aproximación, sugerimos probar fuera del buildout receta en Capítulo 16,
Despliegue de Servidor, el cual va uno da un paso más allá de este modo por utilizar
buildout para crear el entorno de caso.
35
Dirige Odoo Casos de Servidor
Preparándose
Tienes un Odoo el caso con su base de datos inicializó, el addons el camino es
correctamente puesto, y el addons la lista es actualizada.
De la interfaz de web
Para instalar un nuevo addon módulo en vuestra base de datos que utiliza la interfaz de web, uso
los pasos siguientes:
1. Conecta al caso que utiliza the cuenta de Administrador. Abierto la carta de Aplicaciones:
36
Capítulo 2
2. Clic en Aplicaciones.
3. Uso la caja de búsqueda para localizar el addon quieres instalar. Aquí es pocos
vierte para ayudar tú en esta tarea:
Activar el filtro No Instalado
Si buscando una funcionalidad concreta addon más que una
funcionalidad ancha addon, sacar el filtro de Aplicaciones
Tipo una parte del nombre de módulo en la caja de búsqueda, y utilizar
esto como
Filtro de módulo
Puedes encontrar que utilizando la vista de lista da algo más legible
esto un
Filtro de módulo
Puedes encontrar que utilizando la vista de lista da algo más legible
De la línea de orden
Para instalar algunos nuevos addons en vuestra base de datos, seguir los pasos siguientes:
1. Encontrar los nombres del addons. Esto es el nombre del directorio que contiene el
archivo
__openerp__.py Con fueradel camino principal.
2. Parón el caso. Si estás trabajando en una base de datos de producción, marca una
copia de seguridad.
3. Corrido la orden siguiente:
$ odoo/odoo.py -c Caso.cfg -d dbname -i addon1,addon2 --parón-
después de que-init
4. Retomar el caso.
Para actualizar un ya instalado addon módulo en vuestra base de datos, seguir los pasos
dados aquí:
1. Encontrar el nombre del addon módulo para actualizar; esto es el nombre del
directorio que contiene el __openerp__.py Archivo without el camino
principal.
2. Parón el caso. Si estás trabajando en una base de datos de producción, marca una
copia de seguridad.
3. Corrido la orden siguiente:
$ odoo/odoo.py -c Caso.cfg -d dbname -u addon1 \ --
parón-después de que-init
4. Retomar el caso.
Cómo trabaja…
El addon instalación de módulo y la actualización son dos estrechamente relacionó
procesos, pero hay algunos diferencias importantes, cuando destacados en el próximos
dos secciones.
Addon Instalación
Cuándo tú insttodo un addon, Odoo comprueba su lista de disponible addons para un
uninstalled addon con el nombre suministrado. Él también controles para las dependencias
de aquel addon y, si cualquiera, él recursively instalarles antes de instalar el addon.
38
Capítulo 2
Addon Actualización
Cuándo actualizas un addon, Odoo controles en su lista de disponible addon módulos para un
instaldirigió addon con el nombre dado. Él también controles para las dependencias inversas de
aquel addon (estos son el addons aquello depende de el actualizado addon), y, si cualquiera, él
recursively actualizarles.
1. Corrido el addon módulo pre pasos de migración, si cualquier (ve Capítulo 9, Dato
de Módulo, para detalles).
2. Carga las definiciones de modelo del código de fuente de la Pitón y actualizar la
estructura de base de datos si es necesario (ve Capítulo 4, Modelos de Aplicación,
para details).
3. Carga los archivos de dato del addon y actualizar los contenidos de base de datos si
es necesario (ve
Capítulo 9, Dato de Módulo para detalles).
4. Actualización el addon demo dato si demo el dato está habilitado en el caso.
5. Si cualquiera, corrido el addon pasos de migración del correo (ve Capítulo 9, Dato de
Módulo para detalles).
39
Dirige Odoo Casos de Servidor
Allí ha más…
Ser prudente sobre la dependencia que maneja. Considerar un caso donde quieres tener el
addons venta, stock_de venta, y la venta_concreta instalado, con la venta_concreta
dependiendo de stock_de venta y stock_de venta que depende de venta. Para instalar
todo tres, sólo necesitas instalar la venta_concreta, cuando él recursively instalar el
dependerencies
Stock_de venta y venta . Para actualizar todo tres, necesitas actualizar venta, cuando
esto recursively actualizar el stock de venta de_dependencias inverso y la
venta_concreta .
Otra parte delicada es cuándo tú añade una dependencia a un addon que ya tiene una versión
instaldirigió. Para continuar con el ejemplo anterior, imagina que añades una dependencia en
accionario_dropshipping en la venta_concreta. Actualizando el addon la
venta_concreta no automáticamente instalar la dependencia nueva, tampoco pidiendo
la instalación de
Venta_specific. En esta situación, puedes conseguir error muy malo mensajes porque el
código de Pitón del addon no es exitosamente cargado pero el dato del addon y las mesas
de modelos en la base de datos son presentes. Para solucionar esto, necesitas parar el caso
y hombreually instalar la dependencia nueva.
40
Capítulo 2
Preparándose
Supone quieres cambiar las direcciones de manera están manejadas en vuestro caso; vuestro
cliente necesita un tercer campo además de Odoo dos (calle y calle2 ) para almacenar
direcciones.
Ciertamente podrías escribir vuestro propio addon para añadir un campo en res.Socio,
pero el asunto es un poco más delicado que parece si quieres la dirección para ser
correctamente formatted en facturas. Afortunadamente, alguien en un mailing la lista te
dices aproximadamente la calle_de dirección_del socio3 addon aquello está mantenido por
el OCA cuando parte del socio-proyecto de contacto.
Los caminos utilizaron en esta receta refleja el diseño propuesto en el Estandarizando
vuestra receta de diseño de directorio de caso.
3. Cambio el addons camino para incluir aquel directorio y actualizar el addons lista
de vuestro caso (ve recetas anteriores, Configurar el addons camino y Actualizar el
addon lista de módulos, de este capítulo).
4. Instalar el socio_añaderess_calle3 addon (ve la receta anterior anterior,
Instala y upgrade local addon módulos).
Cómo trabaja…
Todo el Odoo repositorios de código de Asociación Comunitarios tienen su addons contuvo
en subdirectorios separados, el cual es coherente con qué esexp ected por Odoo con
respecto a los directorios en el addons camino; por tanto, justo clonando el repositorio en
algún lugar y añadiendo que ubicación en el addons el camino es bastante.
Allí ha más…
Algunos maintainers seguir una aproximación diferente y tener uno addon módulo por
repositorio, viviendo en la raíz del repositorio. En aquel caso, necesitas crear un
directorio nuevo, el cual te añadirá al addons camino y clonar todo el addons de aquel
maintainer necesitas en este directorio. Recuerda para actualizar el addon lista de
módulos each tiempo añades un clon de repositorio nuevo.
41
Dirige Odoo Casos de Servidor
Preparándose
Supone informaste un asunto con calle_de dirección_del socio3 y recibió una notificación
que el asunto estuvo solucionado en la revisión durada de la 9.0 rama del socio-proyecto
de contacto, querrás actualizar vuestro caso con esta versión más tardía.
4. Crear una etiqueta local para el proyecto de modo que puedes revert a
aquella versión en rotura de cosas del caso:
$ git checkout 9.0
$ git Etiqueta 9.0-antes de que-actualización-$(fecha --iso)
Cómo trabaja…
Esto es justo una aplicación sencilla de todas las recetas anteriores hemos visto;
conseguimos una versión nueva del addon y actualizamos él en nuestros casos.
Si git atracción --ff-único falla, puedes revert a la versión anterior que utiliza esta
orden:
$ git Reinicialización --duro 9.0-antes de que-actualización-$(fecha --
iso)
Entonces, puedes probar git atracción (sin --ff-único), el cual causará un fusionar,
pero esto significa tienes cambios locales en el addon.
Ve también
Si las roturas de paso de la actualización, refiere al Actualizando Odoo de receta de Fuente
en Capítulo 1,
Instalando el Odoo Entorno de Desarrollo, para las instrucciones de recuperación.
Recuerda a siempre probar una actualización en una copia de una producción de base
de datos primero.
Preparándose
Cuando en la receta anterior, suponerte informó un asunto con calle_de dirección_del
socio3 y recibió una notificación que el asunto estuvo solucionado en una petición de
atracción, el cual no es todavía fusionado en la 9.0 rama del proyecto. El desarrollador te
preguntas para validar el fijar en PR #123. Necesitas to actualiza un caso de prueba con
esta rama.
No tendrías que probar fuera de tales ramas directamente en una base de datos de
producción, tan primero crear un entorno de prueba con una copia de la base de datos de
producción (ve Capítulo 1, Instalando el Odoo Entorno de Desarrollo, y C hapter 16,
Despliegue de Servidor).
43
Dirige Odoo Casos de Servidor
1. Parón el caso.
2. Va al directorio donde socio-contactar wcuando clonó:
$ cd ~/odoo-dev/mi-odoo/src
3. Crear una etiqueta local para el proyecto de modo que puedes revert a aquella
versión en rotura de cosas del caso:
$ git checkout 9.0
$ git Etiqueta 9.0-antes de que-actualización-$(fecha --iso)
Cómo trabaja…
Estamos utilizando un GitHub característica que habilita peticiones de atracción para ser
estirados por numera utilizar la atracción/nnnn/nombre de rama de la cabeza, donde
nnnn es el número del PR. El git orden de atracción fusionará el remoto brancho en el
nuestro, aplicando los cambios en nuestra base de código. Después de que esto,
actualizamos el addon módulo, prueba, e informe atrás al autor del cambio sobre cualquier
fracaso o éxito.
44
Capítulo 2
Allí ha más…
Puedes repetir paso cuatro para different peticiones de atracción en el mismo repositorio si
les quieres probar simultáneamente. Si eres realmente feliz con el resultado, puedes crear
una rama para mantener una referencia al resultado del aplicó cambios:
$ git checkout -b 9.0-hecho de encargo
45
3
Creando Odoo Módulos
En este capítulo, cubriremos los temas siguientes:
Introducción
Todos estos componentes que nosotros justo mencionados será dirigido en detalle en
capítulos más tardíos.
Ahora que we tiene un entorno de desarrollo y saber cómo para dirigir Odoo casos
de servidor y bases de datos, puedes aprender cómo para crear Odoo addon
módulos.
Nuestro objetivo principal aquí es para entender cómo un addon el módulo está
estructurado y el típico incremental workflow para añadir componentes a él.
Para este capítulo, estás esperado para tener Odoo instalado y para seguir las recetas
en
Capítulo 1, Instalando el Odoo Entorno de Desarrollo. Eres también esperado para
ser cómodo en descubrir e instalando extra addon módulos, cuando descritos en el
Capítulo 2, Dirigiendo Odoo Casos de Servidor, recetas.
47
Creando Odoo Módulos
Preparándose
Necesitaremos un Odoo caso a punto para utilizar.
2. Escoger un technical nombre para el módulo nuevo y crear un directorio con aquel
nombre para el módulo. Para nuestro ejemplo utilizaremos mi_módulo:
$ mkdir Local-addons/mi_módulo
48
Capítulo 3
Cómo trabaja…
Un Odoo el módulo es un directorio conteniendo archivos de código y otras ventajas. El
nombre de directorio utilizó es el nombre técnico del módulo. La llave de nombre en el
módulo manifiesta es su título.
Los módulos pueden ser instalados directamente de la línea de orden que utiliza el --init,
o -i , opción. Antiguamente, tuvimos que utilizar la Lista de Módulo de la Actualización
para hacerlo disponible al Odoo caso. Aun así, en este momento, esto está hecho
automáticamente cuándo el --init or --la actualización está utilizada de la línea de orden.
Preparándose
Tendríamos que tener un módulo para trabajar con, ya conteniendo un __openerp__.py
Manifiesta archivo. Puedes querer seguir la receta anterior para proporcionar tal módulo
para trabajar con.
1. Para crear un manifestar archivo con las llaves más pertinentes, editar el módulo
__openerp__. py Archivo para parecer esto:
# -*- Codificación: utf-8 -*-
{
'Nombre': "Título",
Esummary': "Corto subtitle frase",
'descripción': """Largo description""",
'autor': "Vuestro nombre",
'Licencia': "AGPL-3",
'Sitio web': "http://www.example.com",
'categoría': 'Uncategorized',
'versión': '9.0.1.0.0',
'Depende': ['base'],
'dato': ['vistas.xml'],
'demo': ['demo.xml'],
}
Cómo trabaja…
La primera línea, conteniendo codificación: utf-8, es necesario para Pitón para
procesar el contenido de archivo como Unicode UTF-8. De este modo, podemos utilizar no-
ASCII caracteres en el manifestar.
El remainincontenido de g es un diccionario de Pitón regular , con llaves y valores. El
ejemplo manifiesta utilizamos contiene las llaves más pertinentes:
f Nombre: Esto es el título para el módulo.
f Resumen: Esto es el subtitle con una descripción de una líneas.
fDescripción: Esto is una descripción larga, escrito en texto sencillo o
ReStructuredText(RST) formato. Es normalmente rodeado por triple cita, utilizado
en Pitón para delimitar multiline textos. Para un RST quickstart referencia, http de
visita://docutils.
sourceforge.net/docs/user/rst/quickstart.html.
50
Capítulo 3
fAutor: Esto es una cuerda con el nombre de los autores. Cuando hay más de
uno,es práctica común para utilizar una coma para separar sus nombres, pero
nota que lo todavía tendría que ser una cuerda, no una lista de Pitón.
fLicencia: Esto es el identificador para la licencia bajo qué el módulo está
hechadisponible. Está limitado a un predefined lista, y la mayoría de opción
frecuente es AGPL-3. Otras posibilidades incluyen LGPL-3, Otro OSI
licencia aprobada, y Otro.
Propietario.
fSitio web: Esto es un URL las personas tendrían que visitar para saber más
sobre el módulo o losautores.
fCategoría: Esto suele organizar módulos en áreas de interés. La lista de la categoría
estándar nombra disponible puede ser visto en https://github.com/odoo/
odoo/blob/Maestro/openerp/addons/dato/de módulo/de módulo_de
base.xml. Pero
Es también posible de definir otros nombres de categoría nuevos aquí.
fVersión: Esto es los módulos ' version números. Pueda ser utilizado por el Odoo
tiendade aplicación para detectar versiones más nuevas para módulos instalados.
Si el número de versión no empieza con el Odoo versión de objetivo (por ejemplo,
8.0), sea automáticamente añadió. No obstante, sea más informativo si
explícitamente declaras el Odoo versión de objetivo, por ejemplo, utilizando
8.0.1.0.0 o 8.0.1.0 en vez de 1.0.0 o 1.0.
fDepende: Esto es una lista con los nombres técnicos de los módulos directamente
dependeencima. Si ninguno, al menos tendríamos que depender de la base
module. No olvida para incluir cualquier módulo que define XML IDs, Vistas, o
Modelos referenced por este módulo. Aquello asegurará que ellos todos cargan en
el orden correcto, evitando duro-a-depurar errores.
fDato: Esto es una lista de caminos relativos a los archivos de dato a load con
instalación de móduloo upgrade. Los caminos son relativos al directorio de raíz del
módulo. Normalmente, estos son
XML y CSV archivos, pero es también posible de tener YAML archivos de dato. Estos
están hablados a fondo en Capítulo 9, Dato de Módulo.
f demo: Esto est liste de caminos relativos a los archivos con dato de manifestación para
cargar.
Estos sólo serán cargados si la base de datos estuvo creada con la bandera de
Dato de la Manifestación habilitó.
La imagen que está utilizado como el icono de módulo es el PNG archivo en icono/de
descripción/estática. png.
Allí ha más
En vez de habiendo la descripción larga en el módulo manifiesta, es posible de tener él en
su archivo propio. Desde entonces versión 8.0, pueda ser reemplazado por un README
archivo, con cualquier un .txt, .rst, o un .md (Markdown) Extensión. Otherwise, incluir
un índice/de descripción.html Archivo en el módulo.
Esta descripción de HTML override una descripción definida en el manifestar archivo.
Preparándose
Estamos esperar para tener un addon directorio de módulo con único el __init__.py Y
__openerp__.py Archivos.
Esto nos tendría que conseguir empezado con una estructura que contiene el más utilizó
directorios, similares a este un:
.
├── __init__.py ├──
__openerp__.py
│
├── controllers
│ └── __init__.py
├── Dato
├── i18n
├──
modelos
│ └── __init__.py
├── Seguridad
├── Estático
│ └── Vistas └──
de descripción
53
Creando Odoo Módulos
Cómo trabaja…
Para proporcionar algún contexto, un Odoo addon el módulo puede tener tres tipos de
archivo:
54
Capítulo 3
fEstático/es donde todas ventajas de web están esperadas para ser colocados.
A diferencia de otros directorios,este nombre de directorio no es justo una
convención, e interior de archivos únicos pueda ser hecho disponible para el Odoo
páginas web. No necesitan para ser mencionados en el módulo manifiesta, pero
tendrá que ser referido a en la plantilla de web. This Está hablado con más detalle
en Capítulo 14, Desarrollo de Sitio web del CMS.
Añadiendo modelos
Los modelos definen las estructuras de dato para ser utilizados por nuestras aplicaciones
empresariales. Estos espectáculos de receta cómo para añadir un modelo básico a un
módulo.
Utilizaremos un ejemplo de biblioteca de libro sencillo para explicar esto; queremos un
modelo para representar books. Cada libro tiene un nombre y una lista de autores.
Preparándose
Tendríamos que tener un módulo para trabajar con. Si seguimos la primera receta en este
capítulo, tendremos un vacíos mi_módulo. Utilizaremos que para nuestra explicación.
55
Creando Odoo Módulos
Después de que esto, la biblioteca nueva.Modelo de libro tendría que ser disponible en nuestro
Odoo caso. Si tenemos las herramientas técnicas activand, podemos confirmar que por mirarlo
arriba en los encuadres | Técnicos
| Modelos de Estructura | de la base de datos.
Cómo trabaja…
Nuestro primer paso era para crear un archivo de Pitón donde nuestro módulo nuevo estuvo
creado.
Odoo Los modelos son objetos derivó del Odoo clase de Pitón del Modelo.
Cuándo un modelo nuevo está definido, es también añadido a un registro de modelo central.
Esto lo hace más fácil para otros módulos a modificaciones de marca más tardía a él.
Los modelos tienen unos cuantos atributos genéricos prefijaron con un underscore. El más
importante uno es nombre _, providing un identificador interno único para ser utilizado
durante el Odoo caso.
Los campos de modelo están definidos tan atributos de clase. Empezamos definir el campo
de nombre del Char tipo. Es conveniente para modelos para tener este campo, porque por
default, está utilizado como la descripción récord cuándo referenced de otros modelos.
También utilizamos un ejemplo de un campo relacional, autor_ids. Define un muchos -
a-mucha relación entre Libros de Biblioteca y los socios — un libro puede tener
muchos autores y cada autor pueden tener muchos libros.
Allí ha mucho más para decir sobre modelos, y serán cubiertos en más profundidad en
Capítulo 4,
Modelos de aplicación.
Luego, tenemos que hacer nuestro módulo consciente de este archivo de Pitón nuevo. Esto
está hecho por el __init__. py Archivos. Desde entonces colocamos el código dentro
del subdirectorio/ de modelos, necesitamos el anteriores init archivo para
importar aquel directorio, el cual tiene que en girar contener otro init el archivo
importador cada cual de los archivos de código allí (justo uno en nuestro caso).
Cambios a Odoo los modelos están activados por upgrading el módulo. El Odoo el servidor
manejará la traducción de la clase de modelo a cambios de estructura de la base de datos.
56
Capítulo 3
A pesar de que ningún ejemplo está proporcionado aquí, la lógica empresarial también puede ser
añadida a estos archivos de Pitón, cualquiera por añadir métodos nuevos alM odel clase, o por
extender existiendo métodos, como crear() o escribir() . Esto está dirigido en Capítulo 5,
Desarrollo de Lado de Servidor Básico.
Preparándose
El addon el módulo que implementa la biblioteca.Modelo de libro, proporcionado en la receta
anterior, está necesitado. Los caminos utilizaron es relativo a nuestro addon ubicación de módulo
(por ejemplo, ~/odoo-
dev/Local-addons/mi_módulo/).
1. Crear el archivo de XML para añadir el dato graba describir la biblioteca de vistas
de interfaz/ de usuario_libro.xml:
<?xml Versión="1.0" codificando="utf-
8"?> <openerp>
<Dato>
<!-- Registros de datos van
aquí --> </datos>
</openerp>
57
Creando Odoo Módulos
Si pruebas y upgrade el módulo ahora, tendrías que ser capaz de ver una opción de
carta superior nueva ( podrías necesitar a refresh vuestro navegador de web). Clicking
Encima tenga que trabajar y abrirá las vistas para Biblioteca Reserva aquello es
automáticamente generated por el servidor.
<Forma>
<Grupo>
<Nombre de nombre="del campo"/>
<Autor de nombre="del campo_ids"
widget="muchos2mucho_grupo"/> </de etiquetas>
<Grupo>
<Liberación de fecha="de
nombre_de campo"/> </grupo>
</Forma>
</Campo>
</Récord>
58
Capítulo 3
<Árbol>
<Nombre de nombre="del campo"/>
<Liberación de fecha="de
nombre_de campo"/> </tree>
</Campo>
</Récord>
<Búsqueda>
<Campo de nombre="de
nombre"/> <de campo
autor="de nombre_ids"/>
<cuerda de filtro="Ningún
Autor"
Ámbito="[('autor_ids','=',Falso)]"/>
</Búsqueda>
</Campo>
</Récord>
Cómo trabaja…
En el nivel bajo, la interfaz de usuario está definida por los registros almacenaron en
Modelos especiales. Los primeros dos pasos crean un archivo de XML vacío para definir los
registros de ser cargados y entonces añadirles a la lista del módulo de los datos archiva para
ser instalados.
Archivos de dato pueden ser anywhere dentro del directorio de módulo, pero la convención
es para el usuario intercara para ser definida dentro de un subdirectorio/ de vistas que
utiliza nombres de archivo después del Modelo la interfaz es para. En nuestro caso, la
biblioteca.Interfaz de libro es en el libro/de biblioteca_de las vistas. xml
Archivo.
59
Creando Odoo Módulos
El paso próximo es para definir un Window Acción para mostrar la interfaz de usuario en
general área del cliente de web. La Acción tiene un Modelo de objetivo definido por
res_modelo y pone el título para mostrar al usuario que utiliza nombre. Estos son justo
los atributos básicos. Apoya atributos adicionales, giving mucho más control de cómo las
Vistas son rendered, como qué Vistas son para ser mostrados, añadiendo filtros en los
registros disponibles, o poniendo default valores. Estos están hablados en detalle en
Capítulo 8, Backend Vistas.
En general, registros de dato son defined utilizando <una etiqueta> récord, pero en
nuestro ejemplo, la Ventana
La acción estuvo definida utilizando la etiqueta_de ventana <> del acto. Esto es un atajo
para crear registros para el ir.Acciones.Modelo_de ventana del acto, donde
Acciones de Ventana están almacenadas.
Ambas Vistas están definidas con un registro en el ir.ui.Modelo de vista. Los atributos
utilizamos es como sigue:
fNombre: Esto es un título identificando esta vista. Es frecuente de ver el XML ID
repitióaquí, pero perfectamente pueda ser un título legible más humano.
f Modelo: Esto es el identificador interno del modelo de objetivo, cuando definido en su
_Atributo de nombre.
fArco: Esto es la arquitectura de vista , donde su estructura es de hecho definió.
Esto esdonde tipos diferentes de Ver diferir de cada otro.
60
Capítulo 3
Vistas de forma están definidas con un elemento <de forma> superior, y su tela es una
verja de dos columnas . Dentro de la forma, <elementos> de grupo suelen verticalmente
componer campos. Dos resultado de grupos en dos columnas con campos, aquello está
añadido utilizando el <campo> element. Los campos utilizan un default widget según su
tipo de dato, pero un concreto widget puede ser utilizado con la ayuda del widget
atributo.
Vistas de árbol son más sencillas; están definidos con un elemento <de árbol>
superior que contiene <elementos> de campo para las columnas para ser mostradas.
Finalmente, añadimos una vista de Búsqueda para expandir la opción de búsqueda en la
caja en el derecho superior. Dentro de la <búsqueda> etiqueta de nivel superior, podemos
tener <campo> y elementos <> de filtro. Elementos de campo son campos adicionales que
puede ser buscado de la caja. Filter Los elementos son predefined el filtro condiciona que
puede el activado con un clic.
Los espectáculos de receta cómo para crear un módulo nuevo que utiliza el scaffold
orden, el cual pondrá en colocar un esqueleto de los directorios de archivos para utilizar.
Preparándose
Necesitamos Odoo instalados y un directorio para nuestros módulos hechos de encargo.
1. Cambio el directorio laborable a dónde querremos nuestro módulo para ser. Esto
puede ser quénunca directorio escoges, pero dentro de un addons camino para ser
útil. Siguiendo las elecciones de directorio utilizaron en la receta anterior, tenga
que ser como sigue:
$ cd ~/odoo-dev/Local-addons
2. Escoger un nombre técnico para el módulo nuevo y utilizar el scaffold orden para
crearlo. Para nuestro ejemplo, escogeremos mi_scaffolded:
$ ~/odoo-dev/odoo/odoo.py scaffold Mi_scaffolded
3. Editar el __openerp__.py default El módulo manifiesta proporcionado y
cambiar los valores pertinentes. Seguramente quieres al menos cambiar el
módulo title en la llave de nombre.
61
Creando Odoo Módulos
$ Árbol mi_scaffolded
mi_scaffolded
├── controllers.py
├── demo.xml
├── __init__.py
├── models.py
├── __openerp__.py
├── Seguridad
│ └── ir.Modelo.Acceso.csv
└── Plantillas.xml
Cómo trabaja…
El scaffold la orden crea el esqueleto para un módulo nuevo basado en una plantilla.
Por default, el módulo nuevo está creado en el directorio laborable actual, pero podemos
proporcionar un directorio concreto donde to crear el módulo, pasándolo cuando un
parámetro adicional.
Por ejemplo:
Allí ha más…
Desafortunadamente, el default la plantilla no adhiere a la corriente Odoo directrices. Podríamos
crear nuestra plantilla propia por copiar el default un, en odoo/openerp/cli/plantillas/
default/, y modificando a traje mejor la estructura descrita en el Organizando la receta de
estructura de archivo de módulo. Una orden similar a esto nos podría conseguir empezado en
aquel:
$ cp -r ~/odoo-dev/odoo/openerp/cli/Plantillas/default ~/odoo-dev/plantilla
Más tarde, podemos utilizar él con la orden siguiente:
62
4
Modelos de
aplicación
En este capítulo, cubriremos los temas siguientes:
fff
f
f
f
f
f
f
f
f
f
f
esentación de Modelo y el orden que Añade
D
campos de dato a un Modelo
e
Utilizando un campo de flotador con
f
configurable la precisión que Añade un campo
i
monetario a un Modelo
n
Adding Campos relacionales a un Modelo
i
Añadiendo una jerarquía a un Modelo
e
Añadiendo validaciones de constreñimiento a un Modelo
n
Añadiendo computó campos a un Modelo
d
Exponiendo Relacionó los campos almacenaron
o
en otros modelos que Añaden las relaciones
l
dinámicas que utilizan campos de Referencia
a
Añadiendo características a un Modelo que utiliza la
r
herencia que Utiliza Modelos Abstractos para
e
características de Modelo reutilizable
p
Utilizando herencia de Delegación para copiar características a
r otro Modelo
Introducción
Para concisely conseguir el punto a través de, las recetas en esta marca de capítulo
adiciones pequeñas a un existiendo addon módulo. Escogimos utilizar el módulo creado por
las recetas en Capítulo 3, Creando Odoo Módulos. A mejor seguir los ejemplos aquí, tendrías
que tener aquel módulo creado y a punto para utilizar.
63
Modelos de aplicación
Preparándose
Esta receta supone que tienes un caso a punto con mi_módulo , cuando descrito en
Capítulo 3, Creating Odoo Módulos.
2. Para tener los registros ordenaron primero por default de más nuevos a
más viejos y entonces por título, añadir el siguiente:
_Orden = 'liberación_de fecha desc, nombre'
Cuándo estamos hacer, nuestro library_book.py el archivo tendría que parecer esto:
# -*- Codificación: utf-8 -*-
De openerp modelos de importación,
clase de campos
LibraryBook(modelos.Modelo):
_Nombre = 'library.Libro'
_descripción = 'Libro de
Biblioteca' _orden =
'liberación_de fecha desc,
nombre' _rec_nombre'hort_nombre'
Campos = de nombre.Char('Título',
requerido=Cierto) campos_de nombre =
corto.Char( Eshort Título') campos_de
liberación = de la fecha.Fecha( esFecha de
arrendamiento')
Autor_ids = campos.Muchos2mcualquier( ess.Socio',
cuerda='Autores')
64
Capítulo 4
Tenemos que entonces upgrade el módulo para tener estos cambia activados en Odoo.
Cómo trabaja…
El primer paso añade un título de descripción más amistoso a la definición del modelo. Esto no es
obligatorio, pero puede ser utilizado por algún addons. Para caso, está utilizado por la
característica de seguir en el correo addon módulo para el texto de notificación cuándo un
registro nuevo está creado. Para más detalles, ve
Capítulo 12, Automatización y Workflows.
Por default, Odoo ordena el records utilizando el interno id valor. Pero esto puede ser
cambiado para utilizar los campos de nuestra elección por proporcionar un _atributo de
orden con una cuerda que contiene una coma-lista separada de nombres de campo. Un
nombre de campo puede ser seguido con el desc palabra clave para tenerlo ordenada en
orden inverso.
Los campos únicos almacenaron en la base de datos puede ser utilizada. No-almacenó
computó los campos no pueden soler registros de clase.
Registros de modelo tienen una representación utilizada cuándo son referenced de otros
registros. Por ejemplo, un usuario_id campo con el valor 1 representa el usuario de
Administrador. Cuándo mostrado en una vista de forma, seremos mostrados el noser
nombre más que la base de datos ID. Por default, el campo de nombre está utilizado. De
hecho, aquello es el default valor para el _rec_atributo de nombre, y es por eso que
es conveniente de tener un campo de nombre en nuestros Modelos.
Si ningún campo de nombre existe en el modelo, un representatel ión está generado con el
modelo e identificadores récord, similares a (biblioteca.Libro, 1).
Allí ha más…
La representación récord es disponible en un nombre de exhibición_mágico el campo
computado añadió automáticamente a todos los modelos desde entonces versión 8.0.
Sus valores están generados ucantar el nombre de método del Modelo_consigue(),
el cual era ya en existencia en anterior Odoo versiones.
Por ejemplo, para tener el título y su fecha de liberación en la representación, como Moby
Dick (1851-10-18), podríamos define el siguientes:
def El
nombre_consigue
(self):
resultado = []
Para récord en self:
resultado.Anexa(
(record.id,
Preparándose
Esta receta supone que tienes un caso a punto con el mi_módulo addon el módulo
disponible, cuando descrito en Capítulo 3, Creando Odoo Módulos.
66
Capítulo 4
Fuera_de_campos = de
impresión.Booleano('Fuera de Impresión?')
Campos_de liberación = de la fecha.Fecha(
esFecha de arrendamiento') la fecha_actualizó
= campos.Datetime('Último Actualizado')
campos = de páginas.Entero('Número de
Páginas') el lector que_valora =
campos.Flotador(
Esader Índice Mediano',
(14, 4), # precisión Opcional (total, decimales),
)
2. Todos estos campos apoyan unos cuantos atributos comunes. Cuando un ejemplo,
podríamos editar las páginas de preceder campo para añadirles:
Campos = de páginas.Entero(
cuerda='Número de Páginas',
default=0,
Ayuda='cuenta de página de libro
Total', agrupa='base.Usuario_de grupo',
declara={'cancelar': [( esadonly',
Cierto)]}, la copia=Cierta,
El índice=Falso,
readonly=Falso,
Requerido=Falso, la
compañía_dependiente=Fal
so,
)
Cuerda='Descripción',
# Opcional:
sanitize=Cierto,
estilo_de
cinta=Falso,
traduce=Falso,
)
Cómo trabaja…
Los campos están añadidos a modelos por definir un atributo en su clase de Pitón. El non-el
campo relacional escribe disponible es como sigue:
f Char Para valores de cuerda.
f Texto para multi-valores de cuerda de la línea.
fSelecciónpara listas de selección. Esto tiene una lista de valores y pares de
descripción. Elvalor que está seleccionado es qué consigue almacenado en la
base de datos, y pueda ser una cuerda o un entero.
fHtmlEs similar al campo de Texto, pero está esperado para almacenar texto rico
en el formato de HTML.fLos camposbinarios almacenan archivos binarios, como
imágenes o documentos.
f Tiendas booleanas valores/Falsos Ciertos.
fFechastores valores de fecha. El ORM les maneja en el formato de cuerda, pero
estánalmacenados en la base de datos como fechas. El formato utilizó está definido
en openerp.Campos.
FORMATO_de FECHA.
fDatetimePara fecha-valores de tiempo. Están almacenados en la base de datos
en un naive tiempo de fecha,en tiempo de UTC. El ORM les representa como
cuerda y también en tiempo de UTC. El formato utilizó está definido en
openerp.Campos.DATETIME_FORMATO.
f Campos de entero necesitan no explicación más lejana.
fCamposde flotador almacenan valores numéricos. La precisión opcionalmente
puede ser defined con unnúmero total de dígitos y pares de dígitos decimales.
fMonetariopuede almacenar una cantidad en una moneda segura; es
también explicado enotra receta.
El primer paso en la receta muestra la sintaxis mínima para añadir cada tipo de campo.
Las definiciones de campo pueden ser expandidas para añadir otros atributos
opcionales, cuando mostrados en paso 2.
Aquí es una explicación para los atributos de campo utilizó:
68
Capítulo 4
Allí ha más…
El campo de Selección también acepta una referencia de función en vez de una lista,
cuando su "atributo" de selección. Esto deja para dinámicamente generó listas de
opciones. Puedes ver un ejemplo de este en el Añadir las relaciones dinámicas que
utilizan receta de campos de la Referencia, donde un atributo de selección es también
utilizó.
La Fecha y Datetime campo objects expone unos cuantos métodos de utilidad que puede
ser conveniente.
La creación automática de estos campos de registro puede ser inutilizada por poner el
_acceso_de registro=atributo de modelo Falso.
Otra columna especial que puede ser añadido a un modelo es activo. Tenga que ser una
bandera Booleana allowing para registros de marca como inactive. Su definición parece
esto:
Campos = activos.Booleano('Activo', default=Cierto)
Por default, registros únicos con conjunto activo a Cierto es visible. Para tenerles
recuperado, necesitamos utilizar un filtro de ámbito con [('activo', '=', False)].
Alternativamente, si el
'Prueba_activa': el valor Falso está añadido al Contexto de entorno, el ORM
no filtrará fuera de inactive registros.
70
Capítulo 4
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
4. Añadir una configuración nueva, poniendo Uso para Reservar Precio y escogiendo
el
Precisión de dígitos:
Cómo trabaja…
El conseguir_precisión() miradas de función arriba del nombre en el Decimal
Unccuracy campo de Uso y regresa un tuple representando precisión de 16 dígitos con
el número de decimales definió en la configuración.
Utilizando esta función en la definición de campo, en vez de tenerlo hardcoded, deja el
usuario de fin para configurar él según sus necesidades.
72
Capítulo 4
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
cuerda='Moneda')
Ahora, upgrade el addon módulo, y los campos nuevos tendrían que ser disponibles en el
Modelo. No serán visibles en vistas hasta que están añadidos a ellos, pero podemos
confirmar su adición por inspeccionar los campos de Modelo en Encuadres | Base de datos |
Técnica Structure | Modelos.
73
Modelos de aplicación
Cómo trabaja…
Los campos monetarios son similares de Flotar campos, pero Odoo es capaz de representarles
correctamente en la interfaz de usuario desde entonces sabe lo que su moneda es a través de
un segundo campo para aquel propósito.
Este campo de moneda está esperado para ser moneda nombrada_id, pero podemos
utilizar cualquier nombre de campo nos gusta mientras está indicado utilizando el campo_de
moneda parámetro opcional.
Te podría gustar saber que la precisión decimal para la cantidad está tomada de la
definición de moneda (el campo_de precisión decimal del res.Modelo de moneda).
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
74
Capítulo 4
2. Para añadir el-a-mucho campo para los libros de un editor, necesitamos extender
el modelo de socio. Para simplicity, añadiremos aquello al mismo archivo de Pitón:
Clase
ResPartner(modelos.Modelo):
_hereda = ess.Socio'
libro_ids =
campos.Uno2muchos(
'Biblioteca.Libro',
'editor_id', cuerda='Publicado
Reserva')
3. El muchos-a-mucha relación entre libros y autores era already creó, pero dejado es
revisit lo:
Clase LibraryBook(modelos.Modelo):
# ...
Autor_ids = campos.Muchos2muchos( ess.Socio',
cuerda='Autores')
4. La misma relación, pero de autores a libros, tendría que ser añadido al modelo de
Socio: clase ResPartner(modelos.Modelo):
# ...
Libro_ids = campos.Muchos2muchos(
'Biblioteca.Libro',
cuerda='Authored
Reserva',
# Relación='libro_de biblioteca_res_socio_rel' #
opcional
)
Ahora, upgrade el addon módulo, y los campos nuevos tendrían que ser disponibles en el
Modelo. No serán visibles en vistas until están añadidos a ellos, pero podemos confirmar su
adición por inspeccionar los campos de Modelo en Encuadres | Modelos | de Estructura de
Base de datos | Técnicos.
Cómo trabaja…
Muchos-a-un campos añaden una columna a la mesa de base de datos del modelo que
almacena la base de datos ID of el registro relacionado. En el nivel de base de datos, un
constreñimiento clave extranjero también será creado para él, asegurando que el
almacenado IDs es una referencia válida a un registro en la mesa relacionada. Ningún índice
de base de datos está creado para estos campos de relación, pero esto a menudo tendría
que ser considerado; pueda ser hecho por añadir el índice de atributo=Cierto.
Podemos ver que hay cuatro más atributos podemos utilizar para muchos-a-un campos:
75
Modelos de aplicación
El ondelete el atributo determina qué pasa cuándo el related el registro está eliminado. Por
ejemplo, qué pasa a Libros cuándo su registro de Editor está eliminado? El default es eset
null', poniendo un valor vacío en el campo. También pueda ser esestricto', el cual
impide el registro relacionado de ser eliminado, o 'cascad e', el cual causa el enlazado récord a
también
Ser eliminado.
El último dos (contexto y ámbito ) es también válido para los otros campos relacionales.
Son mayoritariamente significativos en el lado de cliente y en el nivel de modelo actúa tan
default valores para ser utilizados en el client-vistas de lado.
fEl contextoañade variables al contexto de cliente cuándo clicking a través del
campo a laregistro relacionado. Podemos, por ejemplo, lo utiliza para
poner default valores en aquella vista.
fEl ámbitoes un filtro de búsqueda utilizó para limitar la lista de relacionado
records disponible para seleccióncuándo escogiendo un valor para nuestro campo.
Ambos contexto y el ámbito están explicados con más detalle en Capítulo 8, Backend Vistas.
Muchos-a-muchas relaciones también no añaden columnas en las mesas para los modelos.
Este type de la relación está representada en la base de datos que utiliza una mesa de
relación intermedia, con dos columnas para almacenar el dos relacionó IDs. Añadiendo una
relación nueva entre un Libro y un Autor crea un registro nuevo en la mesa de relación con el
ID para el Libro y tél ID para el Autor.
Odoo Automáticamente maneja la creación de esta mesa de relación. El nombre de mesa de la
relación es, por default, construyó utilizar el nombre del dos relacionó modelos más un _rel
sufijo. Pero, podemos override lo utilizando el atributo de relación. Un caso to mantiene en
la mente es cuándo los dos nombres de mesa es bastante grande para la base de datos
automáticamente generada identificadores para superar el
PostgreSQL Límite de 63 caracteres.
Como regla de pulgar, si los nombres de los dos relacionaron las mesas superan 23
caracteres, tendrías que utilizar el atributo de relación para poner nombre más a escaso.
En la sección próxima, iremos a más detalle en este.
Allí ha más…
El Muchos2un campos apoyan un coche adicional_une atributo. Es una bandera que
deja el ORM para utilizar SQL une en este campo. Because De este, él bypasses el habitual
ORM control como control de acceso del usuario y reglas de acceso récord. En un caso
concreto, pueda solucionar un asunto de rendimiento, pero está aconsejado para evitar
utilizándolo.
76
Capítulo 4
Hemos visto la manera más corta a define los campos relacionales. Para completeness,
estos son los atributos concretos a este tipo de campo:
El2muchos atributos de campo son como sigue:
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
2. Para crear el modelo de Categoría del Libro con el parent y relaciones de niño,
crear los modelos/library_book_categ.py archivo con el siguiente:
# -*- Codificación: utf-8 -*-
De openerp modelos de importación,
campos, api clase
BookCategory(modelos.Modelo):
_Nombre =
'biblioteca.Libro.Categoría'
campos = de
nombre.Char('Categoría')
parent_id = campos.Muchos2un(
'Biblioteca.Libro.Categorí
a', cuerda='Categoría de
Padre', ondelete=
esestricto', el
índice=Cierto)
Niño_ids = campos.Uno2muchos(
'biblioteca.Libro.Categoría', 'padre_id',
cuerda='Categorías de Niño')
78
Capítulo 4
4. Para añadir un control que impide looping relaciones, añadir la línea siguiente al
modelo:
@api.Apremia('padre_id') def
_jerarquía_de control(self):
Si no self._Recursión_de
control(): levanta
modelos.ValidationError(
'Error! No puedes crear categorías recursivas.')
Cómo trabaja…
Pasos 1 y 2 crea el nuevo model con hierarchic relaciones. El Mucha2una relación añade un
campo a referencia el registro de padre. Para niño más rápido descubrimiento récord, este
campo es indexed en la base de datos que utiliza el índice=parámetro Cierto. El
padre_id el campo tiene que haber ondelete puesto a cualquiera 'cascade' o
esestricto'.
Al llegar a este punto, tenemos todo aquello está requerido para tener un hierarchic
estructura. Pero hay unos cuantos más adiciones podemos hacer para realzarlo.
El2mucha relación no añade cualesquier campos adicionales a la base de datos pero
proporciona un sh ortcut para acceder todos los registros con este registro como su
padre.
En paso 3, activamos el soporte especial para jerarquías. Esto es útil para alto-leído pero
abajo-escribir instrucciones, desde entonces trae el dato más rápido que explora a expensas
de más costoso escribe operations. Está hecho por añadir dos helper campos, el
padre_dejado y derecho_de padre , y poniendo el atributo de modelo a _tienda_de
padre=Cierta . Cuándo este atributo está habilitado, el dos helper los campos soler dato de
tienda en búsquedas en el hierarchic árbol.
Por default, está supuesto que el campo para que así conste el padre se apellida
padre_id, pero un nombre diferente puede ser utilizado. En aquel caso, el nombre de
campo correcto tendría que ser indicado utilizando el padre de atributo de _modelo
adicional_nombre. El default es como sigue:
_parent_Nombre = 'padre_id'
Paso 4 está aconsejado para impedir cyclic dependencias en la jerarquía— que es, habiendo
un récord ambos en el ascendentes y descendiendo árboles. Esto es peligroso para
programas que navigate a través del árbol, desde entonces pueden conseguirint o un bucle
infinito. Los modelos.El modelo proporciona un método de utilidad para este
(_recursión_de control) que hemos reused aquí.
79
Modelos de aplicación
Allí ha más…
La técnica mostrada aquí tendría que ser utilizado para "jerarquías" estáticas, los cuales están
leídos y queried a menudo pero raramente actualizó. Categorías de libro son un ejemplo bueno ,
desde la Biblioteca no
Continuamente estar creando categorías nuevas, pero los lectores a menudo serán
restringiendo sus búsquedas a una categoría y todas sus categorías de niños. La razón
parath es mentiras en la implementación del Nested Pone Modelo en la base de datos, el
cual requiere una actualización del padre_dejado y padre_columnas correctas (y los
índices de base de datos relacionados) para todos los registros siempre que una categoría
está insertada, sacado, o movió. Esto puede ser una operación muy cara , especialmente
cuándo las ediciones múltiples están siendo actuadas en paralelo transacciones.
Anuncioding validaciones de
constreñimiento a un Modelo
Los modelos pueden tener las validaciones que les impiden de introducir undesired
condiciones. Dos tipos diferentes de constreñimiento pueden ser utilizados: los
comprobados en el nivel de base de datos y los comprobados en el nivel de servidor.
Database Constreñimientos de nivel están limitados a los constreñimientos apoyados por
PostgreSQL. El más generalmente utilizado es la UNIQUE constreñimientos, pero CONTROL
y EXCLUIR los constreñimientos también pueden ser utilizados. Si estos no son bastante
para nuestras necesidades, podemos utilizar Odoo nivel de servidor apremiats, escrito en
código de Pitón.
Utilizaremos el modelo de Libro de la Biblioteca creado en Capítulo 3, Creando Odoo Módulos,
y añadir un par de constreñimientos a él. Añadiremos un constreñimiento de base de datos
que impide títulos de libro duplicado, y un constreñimiento de modelo de la Pitón que impide
fechas de liberación en el futuro.
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
80
Capítulo 4
Después de que these los cambios están hechos al archivo de código, un addon módulo
upgrade y el servidor retoma está necesitado.
Cómo trabaja…
El primer paso tiene un constreñimiento de base de datos creado en la mesa del modelo. Está
aplicado en el nivel de base de datos. El _sql_modelo de constreñimientos atribuye unccepts
una lista de constreñimientos para crear. Cada constreñimiento está definido por un tres
elemento tuple; están listados como sigue:
81
Modelos de aplicación
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
Un Odoo retomar seguido por un módulo upgrade tendría que ser necesitado a
correctamente activar estas adiciones nuevas.
83
Modelos de aplicación
Cómo trabaja…
La definición de un campo computado es el mismo tan el para un campo regular, exceptúa
que un computar el atributo está añadido a specify el nombre del método para utilizar para
su computación.
La semejanza puede ser engañosa, desde entonces computó los campos son
internamente bastante diferentes de campos regulares. Computó los campos son
dinámicamente calculados en runtime, y a no ser que específicamente añades that te
apoyar, no son writeable o searchable.
La función de computación es dinámicamente calculada en runtime, pero el ORM usos
caching para evitar inefficiently recalculating él cada vez su valor está accedido. Tan,
necesita saber lo que otro fields depende de, utilizando el @depende decorator para
detectar cuándo su cached los valores tendrían que ser invalidados y recalculated.
Escribe el soporte puede ser añadido por implementar el inverse función; utiliza el valor
asignó al campo computado para actualizar elo rigin campos. Naturalmente, este sentido de
marcas único para cálculos más sencillos; no obstante, hay casos quietos donde lo puede
ser útil. En nuestro ejemplo, lo hacemos posible para poner la fecha de liberación del libro
por editar los Días Desde entonces Liberan campo computado.
Esun lso posible de hacer searchable un no-almacenó campo computado por poner el
atributo de búsqueda al nombre de método para utilizar (similar de computar e
inverse).
Aun así, este método no es esperado para implementar la búsqueda real. En cambio, recibe tan
parámetros el operador y valorar utilizado para buscar en el campo y está esperado para regresar
un ámbito con las condiciones de búsqueda de la sustitución para utilizar. En nuestro ejemplo,
traducimos una búsqueda de los Días Desde entonces campo de Liberación a una condición de
búsqueda equivalente en la Liberación Dcomió campo.
84
Capítulo 4
Preparándose.
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Crea Odoo Módulos.
cuerda='Editor')
Finalmente, necesitamos a upgrade el addon módulo para los campos nuevos para ser
disponibles en el Modelo.
Cómo trabaja…
Relacionó los campos son justo como campos regulares, pero tienen el atributo adicional,
relacionado, con una cuerda para la cadena separada de campos to traverse.
En nuestro caso, accedemos el Editor relacionó récord a través de editor_id , y entonces
leído su campo de ciudad. También podemos tener cadenas más largas, como
editor_id.País_
id.Código_de país.
85
Modelos de aplicación
Allí ha más…
Relacionad los campos son de hecho computó campos. Justo proporcionan una sintaxis
de atajo conveniente para leer valores de campo de relacionó modelos. Como campo
computado, esto significa que el atributo de tienda es también disponible a ellos. Como
atajo, también tienen todo el attributes del referenced campo, como nombre,
translatable, requerido, y tan encima.
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
selección='_referencable_modelos', la cuerda=
esference Documento')
86
Capítulo 4
Cómo trabaja…
Campos de referencia son similares a muchos-a-un campos, exceptúa que dejan el usuario
para seleccionar el modelo para enlazar a.
El target el modelo es seleccionable de una lista proporcionada por el atributo de
selección. El atributo de selección tiene que ser una lista de dos elemento tuples,
donde el primero es el modelo identificador interno, y el segundo es una descripción
de texto para él.
Aquí es un ejemplo:
Aun así, más que proporcionar una lista fija, podemos utilizar una lista de modelo
configurable por usuarios de fin. Aquello es el propósito del construido-en Referenceable
los modelos disponibles en los Encuadres
| Base de datos | técnica Structure opción de carta. El identificador interno de este
modelo es res. Petición.Enlace.
Nuestra receta empezada con proporcionar una función para explorar todo el Modelo
graba que puede ser referenced a dinámicamente construir una lista para ser
proporcionada al atributo de selección. A pesar de que both las formas están dejadas,
declaramos el interior de nombre de la función cita, en vez de una referencia directa a la
función sin cita. Esto es más flexible, y por ejemplo, deja para el referenced función para
ser definida sólo más tarde en el código, el cual es something aquello no es posible
cuándo utilizando una referencia directa.
87
Modelos de aplicación
Preparándose
Nosotros reutilización el mi_module addon módulo de Capítulo 3, Creando Odoo Módulos.
Finalmente, necesitamos a upgrade el addon módulo para las modificaciones para tomar
efecto.
Cómo trabaja…
Cuándo una clase de modelo is definió con el _heredar atributo, añade
modificaciones al modelo heredado más que reemplazarlo.
88
Capítulo 4
Esto significa que los campos definieron en la clase de heredar está añadida o
cambiado en el modelo de padre. En la capa de base de datos, está añadiendo campos
en la misma mesa de base de datos.
Los campos son también incrementally modificó. Esto significa que si el campo ya existe en
el super clase, sólo los atributos declararon en la clase heredada está modificada; el otro
unos están mantenidos tan en el parent clase.
Los métodos definieron en la clase de heredar reemplaza el método en la clase de padre. Tan,
a no ser que incluyen una llamada a la versión del padre del método, perderemos
características. Debido a este, cuándo queremos añadir lógica a existir métodos, ellos should
incluir una declaración con super para llamar su versión en la clase de padre. Esto está
hablado con más detalle en Capítulo 5,
Lado de Servidor básico Registro Empresarial.
Allí ha más…
Con el _heredar herencia tradicional, es también posible de copiar el padre model
características a un modelo completamente nuevo. Esto está hecho por sencillamente
añadiendo un _atributo de modelo del nombre con un identificador diferente. Aquí
es un ejemplo:
Clase
LibraryMember(modelos.Modelo):
_hereda = ess.Socio'
_Nombre = 'biblioteca.Miembro'
El modelo nuevo tiene su mesa de base de datos propia con su dato propio totalmente
independiente del res.Modelo de padre del socio. Desde entonces todavía hereda
del modelo de Socio, cualesquier modificaciones más tardías a él también afectará el
modelo nuevo.
En la documentación oficial, esto se apellida prototype herencia, pero en práctica, es
raramente utilizó. La razón es que herencia de delegación normalmente contesta a aquella
necesidad en una manera más eficaz, sin la necesidad a estructuras de dato duplicado. Para
más información encima lo, puedes referir al Uso Delegatherencia de ión para copiar
características a otra receta de Modelo.
89
Modelos de aplicación
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
def
Hacer_archivo(self)
: para récord en
self:
Récord.Activo = no récord.Activo
Un upgrade al addon el módulo está necesitado para los cambios para ser activados.
Cómo trabaja…
Un modelo Abstracto está creado por una clase basada en modelos.AbstractModel En vez
de los modelos habituales.Modelo. Tiene todos los atributos y capacidades de modelos
regulares; la diferencia es que el O Mno creará una representación real para él en la base de
datos. Tan,
No pueda tener ningún dato almacenado en él. Sirve sólo como plantilla para una
característica reutilizable que es para ser añadido a modelos regulares.
90
Capítulo 4
Nuestro Archivo el modelo abstracto es quite sencillo; justo añade el campo activo y un
método a toggle el valor de la bandera activa, el cual esperamos a más tarde ser
utilizados vía un botón en la interfaz de usuario.
Cuándo una clase de modelo está definida con el _heredar atributo, hereda el atributo
methods de aquellas clases, y qué está definido en nuestra clase añade las modificaciones
a estas heredaron características.
El mecanismo en jugar aquí es el mismo tan aquello para una extensión de modelo regular
(cuando por el Añadir características a un Modelo que utiliza receta de herencia). Puedes
haber notado que aquí, _hereda utiliza una lista de identificadores de modelo en vez de una
cuerda con un identificador de modelo. De hecho, _hereda puede tener ambas formas.
Utilizando la forma de lista nos dejo para heredar de múltiple (normalmente Abstracto)
clases. En este caso, somos inheriting justo uno, así que una cuerda de texto sería bien. Una
lista estuvo utilizada en cambio para subrayar que una lista puede ser utilizada.
Allí ha más…
Un digno de mención construido-en el modelo abstracto es ir.needaction_mixin.
Deja para registros de señalar que una acción de usuario está necesitada encima les y
es ampliamente utilizado junto con la Red Social messaging características.
Otro ampliamente el modelo abstracto utilizado es correo .Hilo, proporcionado por el
correo (Habla) addon módulo. Habilita, en modelos, el mensaje presenta que poder la
pared de mensaje vista enel bo ttom de muchas formas.
Otro que AbstractModel, un tercer tipo de modelo es disponible:
modelos.TransientModel.
91
Modelos de aplicación
Preparándose
Nosotros reutilización el mi_módulo addon módulo de Capítulo 3, Creando Odoo Módulos.
Ahora, tenemos que upgrade el addon módulo para tener los cambios activaron.
92
Capítulo 4
Cómo trabaja…
El _hereda el modelo entributo pone los modelos de padre que queremos heredar de. En
este caso, justo uno: res.Socio. Su valor es un diccionario de valor clave donde las
llaves son el heredó modelos, y los valores son los nombres de campo utilizó para enlazar
a ellos. Estos son Muchos 2un campos que también tenemos que definir en el modelo. En
nuestro ejemplo, socio_id es el campo que soler enlace con el modelo de padre del
Socio.
A mejor entender cómo trabaja, dejado mirada en qué pasa en el nivel de base de datos
cuándo creamos un Miembro nuevo:
f Un registro nuevo está creado en el res_mesa de socio
f Un registro nuevo está creado en la mesa_de miembro de la biblioteca
fElsocio_idel campo de lamesa_de miembrode la biblioteca está
puesto aliddelres_el socio graba aquello está creado para él
El registro de Miembro es automatically enlazó a un registro de Socio nuevo. Es justo un
muchos-a-una relación, pero el mecanismo de delegación añade alguna magia de modo que
los campos del Socio están vistos como si perteneciendo al registro de Miembro, y un registro
de Socio nuevo es también automáticamente creado con eln ew Miembro.
Te podría gustar saber que esto Socio creado automáticamente el registro ha nada de
particular aproximadamente lo. Es un Socio regular , y si exploras el modelo de Socio,
serás capaz de encontrar aquel registro (sin el dato de Miembro adicional, naturalmente).
Todos los Miembros son al mismo tiempo Socios, pero sólo algunos Socios son también
Miembros.
Tan, qué pasa si eliminas un Socio graba aquello es también un Miembro? Decides por
escoger el ondelete valor para el campo de relación. Para socio_id, utilizamos
cascade. Esto significa que eliminando el Socio también eliminaría el Miembro
correspondiente. Podríamos haber utilizado el encuadre más conservador restringe para
prohibir eliminando el Socio mientras tiene un Miembro enlazado. En este caso, sólo
eliminando el Miembro trabajaría.
Es importante de notar aquella herencia de delegación trabajos únicos para campos y no
para métodos.
Tan, si el modelo de Socio tiene un _algo() método, el modelo de Miembros no
automáticamente lo hereda.
Allí ha más…
Un caso digno de mención de delegación heredaance es el modelo de Usuarios,
res.Usuarios. Hereda de Socios (res.Socio). Esto significa que algunos de los campos
que te puede ver en el Usuario es de hecho almacenado en el modelo de Socio
(notablemente el campo de nombre). Cuándo un Usuario nuevo está creado, también
conseguimos un nuevos automatically creó Socio.
También tendríamos que mencionar que herencia tradicional con _hereda puede también
características de copia a un modelo nuevo, a pesar de que en una menos manera eficaz.
Esto estuvo hablado en el Añadir características a un Modelo que utiliza receta de herencia.
93
5
Lado de Servidor
básico
Desarrollo
En este capítulo, cubriremos los temas siguientes:
fff
f
f
f
f
f
f
f
f
f
y utilizar el API decorators
D
ef Informando errores al usuario
in Obteniendo un vacío recordset para un
ie
n diffemodelo de alquiler que Crea registros nuevos
d Actualizando valores de recordset
o
m los registros que Buscan registros
ét Combinando recordsets
o
d Filtrando recordsets
o Traversing recordset
s
d relaciones
e Extendiendo la lógica empresarial definida en un
m modelo
o
d Extendiendo escribe() y crear()
el Customizing Cómo los registros están buscados
o
Introducción
En Capítulo 4, Modelos de Aplicación, hemos visto cómo para declarar o extender modelos
empresariales en módulos hechos de encargo. Las recetas en aquella cubierta de capítulo
que escribe métodos para computó campos así como métodos para apremiar tvalora de
campos. Este foco de capítulo en el basics de desarrollo de lado del servidor en Odoo—
definiciones de método, recordset manipulación, y extendiendo heredó métodos.
95
Desarrollo de Lado de Servidor básico
Preparándose
Esta receta supone tienes un instance a punto, con el mi_módulo addon el módulo
disponible, cuando descrito en Capítulo 3, Creando Odoo Módulos. Necesitarás añadir
un campo estatal al LibraryBook el modelo definió como sigue:
De openerp modelos de importación,
campos, api clase
LibraryBook(modelos.Modelo):
# […]
Campos = estatales.Selección([('borrador',
'Inutilizable'),
('disponible',
'Disponible'), ('tomado
prestado', 'Tomado
prestado'), ('perdido',
'Perdido')], estate')
Complacer referir a Capítulo 4, Añadiendo campos de dato a un Modelo para más claridad.
96
Capítulo 5
2. Añadir un método para cambiar el estado de algunos libros a un nuevos uno pasado
como un argumento:
@api.multi
def Estado_de cambio(self,
estado_nuevo): para libro en
self:
Si book.is_transición_dejada(libro.Estado estatal
,_nuevo):
Libro.Estado =
nuevo_estatal más:
Continúa
Cómo trabaja…
El código en la receta define dos métodos. Son métodos de Pitón normal , habiendo self
como su primer argumento y puede tener argumentos adicionales también.
Los métodos están decorados con decorators del openerp.api Módulo. Estos decorators es allí
para asegurar la conversión de llamadas hizo utilizar el viejo o tradicional API al nuevo API. El
viejo API está utilizado por la llamada de procedimiento remota (RPC) protocolo del cliente de web
y por módulos que no ha sido todavía ported al nuevo API. Una parte clave de esta conversión
esth e creación de un entorno de ejecución almacenado en self.env; Contiene el siguiente:
Allí ha más…
Hay algunos factores importantes que vale entender.
El @api.Un decorator
Puedes encontrar el @api.Uno decorator mientras leyendo código de fuente. En Odoo 9.0,
este decorator es deprecated porque su comportamiento puede ser confundir—al principio
mirada, y sabiendo de @api.multi , parece este decorator deja el método para apellidarse
sólo en recordsets de medida 1, pero él no. Cuándo viene a recordset longitud, @api.Uno
es similar a @api. multi, pero él un para bucle en el recordset fuera del método y agrega
el valor regresado de cada iteración del bucle en una lista, el cual está regresado al
llamador. Evita utilizar él en vuestro código.
Ve también
En Capítulo 8, Backend Vistas, refiere a los botones de Añadir para formar receta para
aprender cómo para llamar tal método de la interfaz de usuario.
98
Capítulo 5
Preparándose
Para utilizar esta receta, necesitas un método, los cuales pueden tener una condición
anormal. Utilizaremos el siguientes un:
Importación os
De openerp immodelos portuarios, campos, api
Clase
SomeModel(modelos.Modelo):
campos = de
dato.Texto('Dato')
@api.multi
def Salva(self, filename):
Camino =
os.Camino.Une('/optar/exportaciones',
filename) con abiertos(camino, 'w') cuando
fobj:
Para récord en self:
fobj.Escribe(récord.Dat
o) fobj.Escribe('\n')
Este método puede fallar debido a asuntos de permiso, o un disco lleno, o un nombre
ilegal, el cual causaría un IOError o un OSError excepción para ser levantada.
99
Desarrollo de Lado de Servidor básico
Levanta UserError('Ilegal filename %s' % filename)
camino = os.Camino.Une('/optar/exportaciones', filename)
Prueba:
Con abierto(camino, 'w')
cuando fobj: para récord
en self:
fobj.write(Récord.Dato)
fobj.Escribe('\n')
exceptúa (IOError, OSError) cuando
exc:
Mensaje = 'Incapaz de salvar archivo:
%s' % exc levanta UserError(mensaje)
Cómo trabaja…
Cuándo una excepción está levantada en Pitón, propaga arriba de la llamada stack hasta que
está procesado. En Odoo, tél RPC capa que respuestas las llamadas hicieron por el cliente de web
coge todas las excepciones y, dependiendo de la clase de excepción, provoque comportamientos
posibles diferentes en el cliente de web.
Allí ha más…
hay unos cuantos más clases de excepción definieron en openerp.Excepciones, todo
derivando el legado de base excepto_orm clase de excepción. La mayoría de ellos es sólo
utilizado internamente, aparte del siguiente:
f Aviso: En Odoo 8.0, openerp.Excepciones.El aviso jugó la función de
UserError En 9.0. Es ahora deprecated porque el nombre era engañoso ( es un
error , no un aviso) y él collided con la Pitón construida-en Advertir clase. Está
mantenido para backward compatibilidad sólo y tendrías que utilizar UserError
en 9.0.
fValidationError: Esta excepción está levantada cuándo un constreñimiento
de Pitón en un campono es respetado. En Capítulo 4, Aplicación Models, refiere
al constreñimiento de Añadir validaciones a una receta de Modelo para más
información.
100
Capítulo 5
Preparándose
Esta receta reutilización el setup del ejemplo de biblioteca en el addon módulo mi_módulo.
Cómo trabaja…
En empezar arriba, Odoo carga todo el modules y combina las varias clases que derivan de
Modelo y definiendo o extendiendo un modelo dado. Estas clases están almacenadas en
el Odoo registro indexed por nombre. El entorno en self.env Proporciona un acceso de
atajo al registro por emular una Pitón dictionary; si sabes el nombre del modelo estás
buscando, self.env[Nombre_de modelo] te conseguirá un vacío recordset para aquel
modelo. Además, el recordset compartirá el entorno de self .
La llamada para buscar() está explicado en los registros de Buscar receta más tarde.
101
Desarrollo de Lado de Servidor básico
Ve también
El Cambiando el usuario que actúa una acción y Llamando un método con un modificado
enviroment recetas en Capítulo 6, Desarrollo de Lado de Servidor Adelantado Técnicas, trata
modificar self.env en runtime.
Preparándose
Necesitas saber la estructura de los modelos para qué quieres crear un registro,
especialmente sus nombres y tipos así como cualesquier constreñimientos que existen en
estos campos (por ejemplo, si algunos de ellos son obligatorios). El res.Modelo de socio
definido en Odoo tiene un número muy grande de campos, y para mantener las cosas
sencillas, sólo utilizaremos unos cuantos de estos. Además, la definición de modelo en Odoo
usos el viejos API. Para ayudar sigues la receta, aquí is un puerto de la definición de modelo
seremos utilizar para el nuevos API:
Clase
ResPartner(modelos.Modelo):
_el nombre = ess.Socio'
Campos = de nombre.Char('Nombre',
requerido=Cierto) campos = de
email.Char('Email')
Campos = de fecha.Fecha('Fecha')
Es_campos = de compañía.Booleano('Esun c ompany')
Padre_id = campos.Muchos2un( ess.Socio', eslated Compañía')
niño_ids = campos.Uno2muchos( ess.Socio', 'padre_id',
'Contactos')
1. Dentro del método que necesidades de crear un socio nuevo, conseguir la fecha
actual formatted como la cuerda esperada por crear():
Hoy_str = campos.Fecha.Contexto_hoy()
102
Capítulo 5
Cómo trabaja…
Para crear un registro nuevo para un modelo, podemos llamar el crear(valores)
método en cualquier recordset relacionó al modelo. Este método regresa un nuevo
recordset de longitud 1 conteniendo el registro nuevo, con los campos valora
especificados en el diccionario de valores.
En el diccionario:
fValores de campo del texto están dados con cuerdas de Pitón (preferentemente
Unicode cuerdas).fFlotadory campode Entero los valores están dados
utilizando flotadores de Pitón o enteros.fBooleanValores de campo están
dados, preferentemente utilizando Pitón booleans o entero.
f Fecha (resp. Datetime) Valores de campo están dados tan cuerdas de Pitón. Campos
de uso.Fecha.
A_cuerda() (resp. fields.datetime.to_Cuerda()) para convertir una
Pitón datetime.Fecha (resp. datetime.datetime) Objeto al formato
esperado.
fValoresde campo binario están pasados como Base64 cuerda codificada. La
base64módulode la Pitón la biblioteca estándar proporciona métodos como
encodestring(s) para codificar una cuerda en Base64.
fMuchos2uncampo los valores son given con un entero, el cual tiene que ser la
base de datos ID de el registro relacionado.
103
Desarrollo de Lado de Servidor básico
Tuple Efecto
(0, 0, dict_val) Crear un registro nuevo que será relacionado al registro principal
(6, 0, id_lista) Crear una relación entre el ser récord creado y existiendo
Registros, cuyo IDs es en la lista de Pitón id_lista
Amonestación: Cuándo utilizado en un Un2muchos, esto sacará
los registros
De cualquier relación anterior
En la receta, creamos los diccionarios para dos contactos en la compañía queremos crear,
y entonces utilizamos estos diccionarios en el niño_ids entrada del diccionario para el
ser de compañía created, utilizando el (0, 0, dict_val) la sintaxis explicó
anteriormente.
Cuándo crear() se apellida en paso 5, tres registros están creados:
f Uno para la compañía de socio principal, el cual está regresado por crear
f Uno para cada de los dos contactos, los cuales son disponibles en récord.Niño_ids
Allí ha más
Si el modelo definió algún default valores para algunos campos, nada de particular
necesita ser hecho; crea() cuidará de computar el default valores para los campos no
presentan en el diccionario suministrado.
Por otro lado, onchange los métodos no son llamados por crear(), porque se apellidan
por el cliente de web durante la edición inicial del registro. Algunos de estos métodos
computan default los valores para campos relacionaron a un campo dado. Cuándo creando
registros a mano tienes que hacer elwo rk tú, cualquiera por proporcionar valores explícitos
o por llamar el onchange métodos. El Llamando onchange métodos en la receta de lado del
servidor en Capítulo 6, Desarrollo de Lado de Servidor Adelantado las técnicas explica cómo
para hacer este.
Preparándose
Esta receta será utilizar el mismo simplificado res.Definición de socio como el Creando
receta de registros nuevos anteriormente. Puedes referir a esta definición simplificada para
saber los campos.
Cómo trabaja…
Los inicios de método por comprobar si el socio pasado como un argumento contiene
exactly uno récord por llamar asegura_un(). Este método levantará una excepción si esto
no es el caso y el procesamiento abortarán. Esto está necesitado, cuando no podemos
añadir los mismos contactos a varios socios al mismo tiempo.
Nota que ninguna suposición está hecha en self. This El método podría ser definido en
cualquier clase de modelo.
Allí ha más…
Hay tres opciones disponibles si quieres escribir valores nuevos a los campos de registros.
105
Desarrollo de Lado de Servidor básico
Opción 2 es para utilizar la actualización() método por pasar unos nombres de campo de
mapeo de diccionario a los valores quieres puesto. Esto también trabajos únicos para
recordsets de longitud 1. Pueda salvar algunos escribiendo cuándo necesitas actualizar los
valores de several campos inmediatamente en el mismo registro.
Aquí es paso 2 de la receta, reescrito para utilizar esta opción:
@api.Modelo
def Añade_contactos(self, socio,
contactos): socio.Asegura_un()
Si contactos:
Hoy = campos.Fecha.Contexto_hoy()
socio.Actualización(
{'Fecha': today,
'Niño_ids': niño_de socio_ids | contactos}
)
Opción 3 es para llamar el escribir() método, pasando unos nombres de campo de mapeo
de diccionario a los valores quieres puesto. Estos trabajos de método para recordsets de
medida arbitraria y actualizará todos los registros con el specified valores en uno operación de
base de datos sola cuándo las dos opciones anteriores actúan una llamada de base de datos
por récord y por campo. Aun así, tiene algunas limitaciones:
Tuple Efecto
Esto creas un registro nuevo que será relacionado al registro
(0, 0, dict_val) principal.
(1, id, dict_val) Esto actualiza el registro relacionado con el especificado ID con el
Suministró valores.
(2, id) Esto saca el registro con el especificado ID del relacionado
Registros y lo elimina from la base de datos.
(3, id) Esto saca el registro con el especificado ID del relacionado
Registros. El registro no es eliminado de la base de datos.
(4, id) Esto añade un registro de existir con el suministrado ID a la lista de
Relacionó registros.
(5, ) Esto sacas todo el relacionó registros, equivalente a llamar
(3, id) para cada relacionado id.
(6, 0, id_lista) Esto crea una relación entre el ser récord actualizado y el
Existiendo registro, cuyo IDs es en la lista de Pitón id_lista.
106
Capítulo 5
Buscando registros
Buscando los registros es también una operación común en empresariales logic métodos.
Estos espectáculos de receta cómo para encontrar todas las compañías de Socio y sus
contactos por nombre de compañía.
Preparándose
Esta receta será utilizar el mismo simplificado res.Definición de socio como el Creando
receta de registros nuevos anteriormente. Puedes referir a this simplificó definición para
saber los campos.
Cómo trabaja…
Paso 1 define el método. Desde entonces no estamos utilizando los contenidos de self ,
decoramos él con
@api.Modelo, pero esto no es enlazado al propósito de esta receta. Entonces, conseguimos un
vacíos recordset para el res.Modelo de socio porque lo necesitamos para buscar
res.Registros de socio.
Paso 2 crea un ámbito de búsqueda en una variable local. A menudo verás esta creación
inlined en la llamada para buscar, pero con ámbitos complejos, es una práctica buena para
definirlo por separado.
Para una explicación llena de la sintaxis de ámbito de la búsqueda, complacer referir a
los filtros de Definir oficialmente listas: receta de Ámbito en Capítulo 8, Backend Vistas.
Paso 3 llamadas la búsqueda() método con el ámbito. El método regresa un recordset
conteniendo todos los registros que emparejan el ámbito, los cuales entonces pueden
ser más allá procesó. En la receta, llamamos el método con justo el ámbito, pero los
argumentos de palabra clave siguientes son también apoyados:
fOffset=N: Esto suele skip elNprimeros registros que partido la consulta.
Estopuede ser utilizado junto con limitar para implementar paginación o
para reducir consumo de memoria cuándo procesando un número muy grande
of registros. Él defaults a 0 .
f Límite=N: regreso como máximo N registros. Por default, no hay ningún límite.
fEspecificación=de clase_del orden: Esto suele fuerza el orden en el
regresadorecordset. Por default, el orden está dado por el _atributo de orden de
la clase de modelo.
fCuenta=booleano: SiCierto, esto regresa el número de registros en
vez delrecordset. Él defaults a Falso .
Allí ha más…
Dijimos que la búsqueda() el método regresó todos los registros que emparejan el ámbito.
Esto no es completamente cierto. El método asegura que registros únicos al cual el usuario
que actúa el search tiene el acceso está regresado. Además, si el modelo tiene un campo
booleano llamó activo y ningún plazo del ámbito de búsqueda está especificando una
condición en aquel campo, entonces una condición implícita está añadida por buscar a
regreso único registros=Ciertos activos. Tan si tú expect una búsqueda para regresar
algo pero tú sólo consiguen vacíos recordsets, ser seguro para comprobar el valor del
campo activo (si presente) y para comprobar para reglas récord.
Ver la receta que Llama un método con un contexto diferente en Capítulo 6, Lado de
Servidor Adelantado Development Técnicas para una manera a no tener la condición =
Cierta activa implícita añadió. Ver el Límite el acceso récord que utiliza receta de
reglas récord en Capítulo 10, Accediendo Seguridad para más información sobre reglas de
acceso de nivel récord.
108
Capítulo 5
Si para alguna razón te encuentras escribiendo consultas de SQL crudo para encontrar
récord IDs, ser seguro para utilizar self.env['Registro.Modelo'].Búsqueda([('id',
'en', tuple(ids)).ids Después de recuperar el IDs para hacer seguro que reglas de
seguridad están aplicadas. Esto es especialmente importante en multicompany Odoo
casos donde las reglas récord suelen asegura discriminación apropiada entre compañías.
Combinando recordsets
A veces, encontrarás que te ha obtenido recordsets cuáles no son exactamente qué
necesitas. Esta receta muestra varias maneras de combinarles.
Preparándose
Para utilizar esta receta, necesitas tener dos o más recordsets para el mismo modelo.
2. Para fusionar dos recordsets a uno asegurando que no hay ningún duplicado en el
resultado, uso la operación siguiente:
Resultado = recordset1 | recordset2
3. Para encontrar los registros que es común a dos recordsets, uso la operación
siguiente: resultado = recordset1 & recordset2
Cómo trabaja…
La clase para recordsets implementa varios operador de Pitón redefinitions, los cuales
están utilizados aquí. Aquí es una mesa de resumen de la Pitón más útil operadores then
puede ser utilizado en recordsets:
hay también en-operadores de sitio +=, -=, &=, y |= , los cuales modifican el operando
izquierdo en vez de crear un nuevo recordset. Estos son muy útiles cuándo actualizando
un registro es
Uno2muchos o Muchos2muchos campos. Ver los valores de Actualizar de
recordset receta de registros anteriormente para un ejemplo.
Allí ha más…
El ordenado() el método ordenará los registros en un recordset. Llamado sin argumentos,
el _atributo de orden del modelo será utilizado. Otherwise, una función puede ser
pasada para computar un comparison llave en la misma moda como la Pitón construida-en
ordenado(secuencia, llave) función. El argumento de palabra clave inverso es
también apoyado.
Filtrando recordsets
En algunos casos, ya tienes un recordset, pero necesitas operar sólo encima algunos
registros. Puedes, naturalmente, itera en el recordset, comprobando para la condición en
cada iteración y suplente dependiendo de el resultado del control. Pueda ser más fácil, y
en algunos casos, más eficaces de construir un nuevos recordset conteniendo sólo los
registros interesantes y llamando una operación sola en aquel recordset.
Estos espectáculos de receta cómo para utilizar el filtro() método para extraer un
recordset de otro.
110
Chapter 5
Preparándose
Nosotros reutilización el simplificado res.Modelo de socio mostrado en el Crear receta
de registros nuevos anteriormente. Esta receta define un método para extraer socios
habiendo una dirección de email de un suministrado recordset.
Cómo trabaja…
La implementación del filtro() método de recordsets crea un vacío recordset en qué
añade todos los registros for cuál la función de predicado evalúa a Cierto . El nuevo recordset
es finalmente regresó. El orden de registros en el originales recordset está preservado.
La receta de preceder utilizó una función interna nombrada. Para tales predicados
sencillos, a menudo encontrarás un unnonymous función de lambda utilizó:
@api.Modelo
def Socios_con_email(self, socios): socios de
regreso.Filtro(lambda p: p.Email)
De hecho, para filtrar un recordset basó en el hecho que uno atribuye es truthy en el sentido
de Pitón, puedes utilizar socios.Filtro('email').
111
Desarrollo de Lado de Servidor básico
Allí ha más…
Mantiene en importar aquel filtro() opera en la memoria. Si estás intentando
optimizar el rendimiento de un método en el camino crítico, puedes querer utilizar
un ámbito de búsqueda o incluso mover a SQL, en el coste de readability.
Estos espectáculos de receta cómo para utilizar el mapped() método a traverse recordset
relaciones; escribiremos dos métodos que actúan el siguientes operations:
f Recuperando los emails de todos los contactos de una compañía de socio
sola pasada como un argumento
f Recuperando las varias compañías a qué algunas socias de contacto están
relacionadas
Preparándose
Seremos reusing el modelo de Socio simplificado mostrado en el Crear receta de
registros nuevos de este capítulo.
2. Llamada mapped() para conseguir las direcciones de email de los contactos del
socio:
Socio de regreso.mapped('Niño_ids.Email')
112
Capítulo 5
Cómo trabaja…
En paso 1, llamamos asegura_un() para hacer seguro tenemos un socio solo. Esto no es
requerido para la receta, cuando mapped() trabaja muy bien en recordsets de medida
arbitraria. Aun así, es mandated por la especificación del método estamos escribiendo,
cuando no queremos recuperar contactos de compañías múltiples por equivocación.
TAquí es más…
Cuándo utilizando mapped(), mantiene en importar que opera en la memoria dentro del Odoo
servidor por repetidamente traversing relaciones y por tanto haciendo consultas de SQL, los
cuales no pueden ser eficaces; aun así, el código es terse y expresivo. Si eres pruebaing para
optimizar un método en el camino crítico del rendimiento de vuestro caso, puedes querer
reescribir la llamada a mapped() y expresar él como búsqueda() con el ámbito apropiado, o
incluso mover a SQL (en el coste
De readability).
El mapped() method también se puede apellidar con una función cuando argumento. En este
caso, regresa una lista que contiene el resultado de la función aplicó a cada registro de self ,
o la unión del recordsets regresó por la función, si la función regresa un recordset.
113
Desarrollo de Lado de Servidor
básico
Ve también
f El Buscar receta de registros
f El Ejecutando receta de consultas de SQL cruda En Capítulo 6, Desarrollo
de Lado de Servidor Adelantado Técnicas
Preparándose
Si quieres seguir la receta, marca seguro tienes el mi_módulo addon de Capítulo 3,
Creando Odoo Módulos, con el brujo de préstamo definido en el Writing un brujo para guiar
la receta de usuario de Capítulo 6, Desarrollo de Lado de Servidor Adelantado Técnicas.
Crear un nuevo addon módulo regreso de préstamo_de
biblioteca_llamado_data aquello depende de mi_módulo. En este módulo,
extender la biblioteca.Libro.Modelo de préstamo como sigue:
Clase
LibraryBookLoan(modelos.Modelo):
_hereda =
'biblioteca.Libro.Préstamo'
Campos_de fecha_de regreso = esperados.Fecha('Previsto para',
requerido=Cierto)
114
Capítulo 5
Duración_de préstamo =
self.Miembro_id.Duración_de préstamo hoy_str
= campos.Fecha.Contexto_hoy() hoy =
campos.Fecha.De_cuerda(hoy_str)
Esperado = hoy + timedelta(duración=de
préstamo_de los días) valores.Actualización(
{'Fecha_de regreso_esperado':
fields.date.to_cuerda(esperado)}
)
Valores de regreso
115
Desarrollo de Lado de Servidor básico
Cómo trabaja…
En paso 1, nosotros refactor el código del Escribiendo un brujo para guiar la receta de
usuario en Capítulo 6, Desarrollo de Lado de Servidor Adelantado Técnicas, para utilizar una
codificación muy común y útil patrón para crear la biblioteca.Libro.Registros de préstamo: la
creación del diccionario de valores está extraído en un método separado más que hardcoded
en el método que llama crea(). Esto alivia extender el addon módulo in caso los valores
nuevos tienen que ser pasados en tiempo de creación, el cual es exactamente el caso
estamos afrontando.
Paso 2 entonces hace la extensión de la lógica empresarial. Definimos un modelo que
extiende biblioteca.Préstamo.Brujo y redefine el _preparar_préstamo()
método. El redefinitinicios de ión por llamar la implementación de la clase de padre:
Valores = super(LibraryLoanWizard, self)._Prepara_préstamo(libro)
Allí ha más…
En esta receta, escogimos extender el comportamiento por llamart él implementación
normal y modificando el resultado regresado después. Es también posible de actuar
algunas acciones antes de llamar la implementación normal, y naturalmente, también
podemos hacer ambos.
Aun así, qué vimos en esta receta es que es más duro a change el comportamiento del medio
de un método. Tuvimos que refactor el código para extraer un punto de extensión a un método
separado y override este método nuevo en el módulo de extensión.
Qué puede you hacer antes y después de llamar la implementación original del método?
Muchas cosas, incluyendo (pero no limitados a):
fModificando los argumentos que está pasado a la implementación original
(antes)fModificando el contexto que está pasado al original implementación
(antes)
fModificando el resultado que está regresado por la implementación
original (después)fLlamando otro método (antes, después)
f Creando registros (antes, después)
f Levantando un UserError para cancelar la ejecución en casos prohibidos (before,
después)
fPartiendoselfen más pequeño recordsets, y llamando la implementación
original en cadade los subconjuntos en una manera diferente (antes)
Estos espectáculos de receta cómo para extender crear() y escribir() para controlar
acceso a algunos campos de los registros.
Preparándose
Extenderemos en el ejemplo de biblioteca del mi_módulo addon módulo en Chapter 3,
Creando Odoo Módulos.
Clase
LibraryBook(modelos.Modelo):
_nombre = 'biblioteca.Libro'
Campos_de comentarios = del director.Texto( soyanager Remarca')
Sisoyanager_remarca' en
valores: levanta
excepciones.UserError(
'No eres dejado para modificar '
soyanager_remarca'
)
Regreso super(LibraryBook, self).Crea(valores)
biblioteca_del grupo'):
Sisoyanager_remarca' en
valores: levanta
excepciones.UserError(
'No eres dejado para modificar '
soyanager_remarca'
)
Regreso super(LibraryBook, self).Escribe(valores)
118
Capítulo 5
allfields=allfields, escribe_el
acceso=escribe_acceso,
atributos=de atributos
)
Si no self.El usuario_tiene_grupos( 'biblioteca.Director_de
biblioteca_del grupo'):
Cómo trabaja…
Paso 1 redefine el crear() método. Utiliza un decorator no hemos visto tan lejos,
@api.Regresos.
Este decorator mapas el valor regresado del nuevo API al viejo API, el
cual está esperado por el RPC protocolo. En este caso, el RPC llamadas
para crear esperan la base de datos id para el registro nuevo de ser
creado, así que pasamos el @api.Regresos decorator un anónimos
functión, el cual fetches el id del registro nuevo regresado por nuestra
implementación. Es también necesitado si quieres extender la copia()
método. No Lo olvida cuándo extendiendo estos métodos si la
implementación de base utiliza el viejo API o chocarás con duro to
interpretar mensajes.
Allí ha más…
Cuándo extendiendo escribe(), nota que antes de llamar el super() implementación de
escribir() , self es quieto unmodified. Puedes utilizar esto para comparar los valores
actuales de los campos a los en el diccionario de valores.
En la receta, escogimos levantar una excepción, pero podríamos haber también sacó el campo
de ofender del diccionario de valores y silenciosamente skipped actualizando que campo en el
registro:
@api.multi
def Escribe(self, valores):
Si no self.El usuario_tiene_grupos( 'biblioteca.Director_de
biblioteca_del grupo'):
Sisoyanager_remarca' en valores:
del Valores[ soyanager_remarca']
Regreso super(LibraryBook, self).Escribe(valores)
Preparándose
Para esta receta, seremos utilizar la definición de modelo siguiente :
Clase
LibraryBook(modelos.Modelo):
_nombre = 'biblioteca.Libro'
Campos = de
nombre.Char('Título') isbn =
campos.Char('ISBN')
Autor_ids = campos.Muchos2muchos( ess.Socio', 'Autores')
@api.Modelo
def El
nombre_consigue
(self):
resultado = []
Para libro en self:
Libro = de
autores.Autor_ids.mapped('Nombre') nombre
= u'%s (%s)' % (libro.Título,
u', '.Une(autores))
resultado.Anexa((book.id, nombre))
Resultado de regreso
Cuándo utilizando este modelo, un libro en un Muchos2un widget está mostrado tan Título de
Libro (Autor1, Autor2...). Los usuarios esperan ser capaces de escribir en un autor name y
encontrar la lista filtrada según este nombre, pero esto no trabajará como el default
implementación de búsqueda_de nombre sólo utiliza el atributo refirió a por el
_rec_atributo de nombre de la clase de modelo, en nuestro caso,
'Nombre'. Como servicio al adelantó usuarios, también queremos dejar filtrando por ISBN
número.
121
Desarrollo de Lado de Servidor básico
Cómo trabaja…
El default implementación de nam e_búsqueda() de hecho sólo llama la _búsqueda_de
nombre() método, el cual el trabajo real. Esta _búsqueda_de nombre() el método tiene un
argumento adicional, el nombre_consigue_uid, el cual está utilizado en algunos casos de
esquina para computar los resultados que utilizan sudo().
1. Genera una lista vacía nueva si args es Ninguno, o hace una copia de args otherwise.
Hacemos una copia para evitar nuestro modifications a la lista habiendo efectos de lado
en el llamador.
2. Entonces, comprobamos si el nombre no es una cuerda vacía o si el operador no es
'ilike'. Esto es para evitar generando un ámbito mudo [('nombre', ilike, '')]
que
No filtra cualquier cosa. En aquel caso, saltamos straight a la llamada al
super() implementación.
3. Si tenemos un nombre, o si el operador no es 'ilike', entonces añadimos
algunos filtrando criterios a args . En nuestro caso, añadimos cláusulas que buscará
el nombre suministrado en el título de los libros, o en su ISBN, o en los autores'
nombres.
4. Finalmente, llamamos el super() implementación con el ámbito modificado en
args y forzando nombre a '' y operador a ilike . Nosotros esto para forzar el
default implementación de _búsqueda_de nombre() a no alterar el ámbito recibe,
so el especificamos es para ser utilizado.
122
Capítulo 5
Allí ha más…
Mencionamos en la introducción que este método está utilizado en el Muchos2un
widget. Para completeness, es también utilizado en las partes siguientes de Odoo:
f Propuestas ent busque widget
fCuándo utilizando elenoperador encimaUno2muchosy
Muchos2muchoscampos en el ámbitofpara buscar registros
enmuchos2muchas_etiquetaswidget
f Para buscar registros en el CSV importación de archivo
Ve también
El Definir la Representación de Modelo y receta de Orden en Capítulo 3, Creando Odoo los
módulos presenta cómo para definir el nombre_consigue() método, el cual suele crear
una representación de texto de un registro.
Los filtros de Definir oficialmente listas: receta de Ámbito en Capítulo 8, Backend las vistas
proporciona más información unbout sintaxis de ámbito de la búsqueda.
123
6
Adelantado
Lado de servidor
Desarrollo
Técnicas
En este capítulo, veremos cómo a:
f
Escribir un brujo para guiar el usuario
f
Define onchange métodos
f
Llamada onchange métodos en el lado de
servidor Portuario viejo API código al
nuevo API
Introducción
En Capítulo 5, Desarrollo de Lado de Servidor Básico, vimos cómo para escribir métodos en
una clase de modelo, cómo para extender métodos de heredó modelos, y cómo para trabajar
con recordsets. Este capítulo trata más adelantó temas como laborables con el entorno de
un recordset y trabajando con onchange métodos.
125
AdelantadoSe rver Técnicas de Desarrollo del Lado
Preparándose
Seremos trabajar en registros del res.Modelo de compañía. Por default, miembros
únicos del Acceso/de Administración Rights grupo de usuario puede modificar registros
de res.Compañía , pero en nuestro caso, necesitamos proporcionar un punto de acceso
para cambiar sólo el número de teléfono a usuarios quiénes no son necesariamente
miembros de aquel grupo.
Cómo trabaja…
En paso 4, llamamos self.sudo(). Este método regresa un nuevo recordset con un
entorno nuevo en qué el usuario no es igual cuando el en self. Cuándo llamado sin un
argumento, sudo() enlazará el Odoo superuser, Administrator, al entorno. Todas llamadas
de método vía el regresados recordset está hecho con el entorno nuevo, y por tanto con
superuser privilegios.
Si necesitas un usuario concreto, puedes pasar cualquiera un recordset conteniendo
que usuario o la base de datos id delu ser. La fragmento siguiente te dejas para buscar
libros que es visible, utilizando el usuario público:
Usuario_público = self.env.ref('Base.Usuario_público')
libro_público =
self.env['Biblioteca.Libro'].sudo(Usuario_público)
hay más…
Cuándo utilizando sudo() sin un argumento, pusiste el usuario del contexto al Odoo superuser.
Este superuser bypasses todas las reglas de seguridad de Odoo, both las listas de control del
acceso y las reglas récord. Por default, este usuario también tiene una compañía_id el campo
puesto a la compañía principal del caso (el con id 1). Esto puede ser problemático en un multi
caso de compañía:
f Si no eres prudente, nuevo records creó en este entorno será enlazado a la
compañía del superuser
f Si no eres prudente, graba buscado en este entorno puede ser enlazado a cualquier
presente de compañía en la base de datos, el cual significa que puedes ser filtrar
información al real usuario, o peor, puedes ser silenciosamente corrompiendo la
base de datos por enlazar los registros juntos que pertenecen a compañías
diferentes
Utilizando sudo() también implica crear un caso de Entorno nuevo. Este entorno tendrá
un inicialmente vacío recordset cache, y que cache evolucionará independientemente del
cache de self.env . Esto puede causar spurious consultas de base de datos. De todas
formas, tendrías que evitar crear entorno nuevo dentro de bucles, e intentar mover estas
creaciones de entorno al outmost alcance posible.
127
Desarrollo de Lado de Servidor adelantado Técnicas
Ve también
fElObtener un vacío recordset para una receta de modelo enCapítulo
5,Desarrollo de Lado de ServidorBásico, explica lo que el entorno es.
Estos espectáculos de receta cómo para leer el nivel accionario para todo
producto.product Modelos en un stock dado.Ubicación.
Preparándose
Esta receta utiliza el accionario y producto addons. Para nuestros propósitos, aquí
es una versión simplificada del producto.Modelo de producto:
Producto de
clase.Producto(modelos.Modelo):
_nombre = 'producto.Producto'
Nombre = fields.Char('Nombre', requerido=Cierto)
qty_campos = disponibles.Flotador('Cantidad a
mano',
Computa='_el producto_disponible')
def _El producto_disponible(self):
"""Si el contexto contiene una 'ubicación' clave
enlazada a una base de datos id, entonces el accionario
disponible está computado dentro de aquella ubicación
sólo. Otherwise El stock de todas las ubicaciones
internas está computado"""
El pase # leído la fuente real en addons/stock/product.py :)
128
Capítulo 6
5. Crear una variedad con el nombre de producto y nivel accionario de todo presente
de productos en la ubicación especificada:
Accionario_levels = []
Para producto en todos los
_productos: si
producto.qty_Disponible:
Niveles_accionarios.Anexa((product.name,
producto.qty_Disponible)
)
Regreso niveles_accionarios
Cómo trabaja…
Paso 3 llamadas self.Con_contexto() con algunos argumentos de palabra clave.
Esto regresa una versión nueva de se lf (cuál es un producto .Producto recordset)
con las llaves añadieron al contexto actual. Estamos añadiendo dos llaves:
fUbicación: Esto uno está mencionado en el docstring
delproducto.Métodode producto que computa el qty_campo
disponible.
fPrueba_activa: Cuándo este key es presente y enlazado alvalorFalso, la
búsqueda() el método no automáticamente añade ('activo', '=',
Cierto) al ámbito de búsqueda. Utilizando este asegura que en paso 4,
conseguimos todos los productos , incluyendo el discapacitados unos.
Allí ha más…
Es también posible de pasar un diccionario a self.Con_contexto() , en which caso el
diccionario está utilizado como el contexto nuevo, overwriting la corriente un. Tan paso 3
también podría haber sido escrito así:
Contexto_nuevo = self.env.Contexto.Copia()
contexto_nuevo.Actualización({'ubicación':
location.id,
'Prueba_activa': Falso})
producto_en_loc =
selfo.Con_contexto(contexto_nuevo)
Ve también
f El Obtener un vacío recordset para una receta de modelo en Capítulo 5, Básico
Server Desarrollo de Lado, explica lo que el entorno es
f Los parámetros de Paso a formas y acciones: receta de Contexto en Capítulo 8,
Backend Vistas, explica cómo para modificar el contexto en acción definiciones
f El Buscar receta de registros en Capítulo 5, Básico Server Desarrollo de Lado,
explica registros activos
Esta receta te muestras cómo para utilizar consultas de SQL crudo para leer
res.Registros de socio agruparon por país.
Consigueting a punto
Seremos utilizar una versión simplificada del res.Modelo de socio:
Clase
ResPartner(modelos.Modelo):
_el nombre = ess.Socio'
Campos = de nombre.Char('Nombre', requerido=Cierto)
130
Capítulo 6
Campos = de email.Char('Email')
Es_campos = de compañía.Booleano('Es una compañía')
Padre_id = campos.Muchos2un( ess.Socio', eslated Compañía')
niño_ids = campos.Uno2muchos( ess.Socio', 'padre_id',
'Contactos')
País_id = campos.Muchos2un( ess.País', 'País')
4. Ejecutar la consulta:
self.env.cr.Ejecuta(sql)
Cómo trabaja…
En paso 3, declaramos un SQL SELECCIONA query. Utiliza el id campo y el país_id
llave extranjera, el cual refiere al res_mesa de país. Utilizamos un GRUPO POR
declaración de modo que la base de datos la agrupación por país_id para nosotros, y la
variedad_agg función de agregación. Esto es un muy útil PostgreSQL extensión a SQL que
pone todos los valores para el grupo en una variedad, el cual mapas de Pitón a una lista.
Paso 4 llamadas el ejecutar() método en el cursor de base de datos almacenado en
self.env.cr. Esto envía la consulta a PostgreSQL y lo ejecuta.
Paso 5 usos el fetchall() método del cursor para recuperar una lista de filas seleccionó
por la consulta. De la forma de la consulta ejecutamos, sabemos que cada fila haber
exactamente dos valores, el primer país de ser_id y el otro un, la lista de ids para los
socios habiendo that país. Nosotros bucle sobre estas filas y crear recordsets de los
valores, el cual almacenamos en el diccionario de resultado.
Allí ha más…
El objeto en self.env.cr es un delgado wrapper alrededor de un psycopg2 cursor.
Los métodos siguientes son los querrás nose la mayoría del tiempo:
fEjecuta(consulta, params): Esto ejecuta la consultade SQLcon los
parámetrosmarcados como %s en la consulta sustituida con los valores en params,
el cual es un tuple
Ve también
f Para administración de derechos del acceso, ve Capítulo 10, Seguridad de Acceso.
Preparándose
Si quieres seguir la receta, marca seguro tienes el mi_módulo addon módulo de
Capítulo 3, Creating Odoo Módulos.
Clase
LibraryBookLoan(modelos.Modelo):
_nombre =
'biblioteca.Libro.Préstamo'
Libro_id = campos.Muchos2un('biblioteca.Libro',
'Libro',
requerido=Cierto)
Miembro_id = campos.Muchos2un('biblioteca.Miembro',
'Borrower',
requerido=Cierto)
Campos = estatales.Selección([('actual',
'Actual'), ('hecho',
Hecho')], estate',
default='Actual', requerido=Cierto)
133
Desarrollo de Lado de Servidor adelantado
Técnicas
3. Crear una vista de forma para el modelo. Añadir la definición de vista siguiente al módulo
views:
<Récord id='forma_de brujo_de préstamo_de biblioteca'
modelo='ir.ui.Vista'> <nombre de campo='nombre'>forma de
brujo de préstamo de biblioteca nombre</de campo> <de campo
de vista= soyodel'>biblioteca.Préstamo.Campo</de brujo>
<Nombre de campo='arco'
tipo='xml'> <cuerda de
forma="Toma prestado libros">
<Hoja>
<Grupo>
<Campo name=
soyrescoldo_id'/> </grupo>
<Grupo>
<Nombre de
campo='libro_ids'/>
</grupo>
<Hoja>
<footer>
<Nombre de botón= es cordón_presta'
Cuerda='VALE'
clase='btn-
'tipo'primarioobjet
o'/>
O
<Cuerda de botón='Cancelar'
clase='btn-default'
especial='cancelar'
/>
</footer>
</Forma>
</Campo>
</Récord>
4. Crear una acción y una entrada de carta para mostrar el brujo. Añadir el
siguiente declarations al archivo de carta del módulo:
<Ventana_de acto id="libros_de préstamo_de
brujo_de acción"
nombran="Préstamos Récord"
134
Capítulo 6
res_Biblioteca="de modelo.Préstamo.Brujo"
view_Objetivo="d
e forma" del
modo="nuevo"
/>
<menuitem id="Libros_de préstamo_de brujo_de
carta" carta="de libro_de
biblioteca_de padre" préstamo="de
brujo_de acción_de
acción_secuencia" de libros="20"
/>
Cómo trabaja…
Paso 1 define un modelo nuevo. Es no diferente de otros modelos, aparte de la clase de
base, el cual es TransientModel en vez de Modelo . Ambos TransientModel y el
modelo comparte una clase de base común llamó BaseModel, y si compruebas el
código de fuente de Odoo, verás que 99 por ciento del trabajo es en BaseModel y que
ambos Modelo y TransientModel es casi vacío.
Las cosas únicas que cambio para TransientModel los registros son como sigue:
fLos registros son periódicamente sacados de la base de datos así que las
mesas para los modelostransitorios no crecen arriba en medida con el
tiempo
fNo puedes definir reglas de acceso enTransientModels. Cualquiera está dejado
para crear unregistro, pero sólo el usuario quién creó un registro lo puede leer y
utilizarlo.
fNo tienes que definirUno2muchoscampos enTransientModelaquello
refiere a un modelonormal, cuando esto añadiría una columna en el modelo
persistente linrey a dato transitorio. Uso Muchos2muchas relaciones en este caso.
Naturalmente puedes definir Muchos2un y Uno2muchos campos para relaciones
entre modelos transitorios.
Definimos dos campos en el modelo, uno para almacenar el miembro que toma prestado los
libros y uno para almacenar la lista de ser de libros tomó prestado. Podríamos añadir otros
campos escalares para grabar una fecha de regreso planificada, para caso.
Paso 2 añade el código a la clase de brujo que se apellidará cuándo el botón definido en paso
3 es clicked encima. Este código lee los valores del brujo y crea
biblioteca.Libro.Registros de préstamo para cada libro.
Paso 3 define una vista para nuestro brujo. Complacer referir al Documento-receta de formas
del estilo en
Capítulo 8, Backend Vistas, para detalles. El punto importante aquí es el botón en el footer:
el atributo de tipo está puesto a 'objeto' , el cual significa que cuándo los clics de usuario en
el botón, el método con el nombre especificado por el atributo de nombre del botón se
apellidará.
135
Desarrollo de Lado de Servidor adelantado Técnicas
Paso 4 marcas seguro nosotros have un punto a favor de entrada nuestro brujo en la carta de la
aplicación. Utilizamos objetivo='nuevo' en la acción de modo que la vista de forma está
mostrada como caja de diálogo sobre la forma actual. Complacer referir al Añadir un Elemento
de Carta y receta de Acción de la Ventana en Capítulo 8,
Backend Vistas, para detalles.
Allí ha más…
Aquí es unos cuantos consejos para realzar vuestros brujos.
Clave Valor
Esto es el nombre del modelo relacionó a la acción. Esto es
Modelo_activo generalmente el
Ser de modelo displayed encima pantalla.
Activo_id Esto indica que un registro solo es activo, y proporciona el ID de aquel
Récord.
Si varios registros estuvieron seleccionados, esto será una lista con el
Activo_ids IDs (esto
Pasa cuándo varios elementos están seleccionados en una vista de árbol
cuándo la acción
Está provocado. En una vista de forma, consigues [activo_id]).
Ámbito_activo Un ámbito adicional en qué el brujo operará.
Estos valores pueden soler computar default valores del modelo, o incluso directamente en el
método llamado por el botón. To Mejora en el ejemplo de receta, si tuvimos un botón mostrado
en la vista de forma de una biblioteca.Modelo de miembro para lanzar el brujo, entonces el
contexto de la creación del brujo contendría {'modelo_activo':
'biblioteca.Miembro', 'activo_id': <miembro id>}. En that caso, podrías definir el
miembro_id campo
Para tener un default el valor computado por el método siguiente:
def _default_Miembro(self):
Si self.Contexto.Consigue('modelo_activo') ==
'biblioteca.Miembro': regreso
self.Contexto.Consigue('activo_id', Falso)
136
Capítulo 6
Miembro = self.Miembro_id
libros = self.Libro_ids
miembro.Toma
prestado_libros(libros)
Recomendamos utilizar la versión en la receta aun así, porque deja reusing el brujo de otras
partes del código por crear registros para el brujo, poniendot dobladillo en un solo recordset
(ve el Combinar recordsets receta en Capítulo 5, Desarrollo de Lado de Servidor Básico, para
ver cómo para hacer este) y entonces llamando préstamos_récord() en el recordset.
Concedido, aquí el código es trivial y tú no realmente necesidad de saltar a través de unll
aquellos hoops para grabar que algunos libros estuvieron tomados prestado por miembros
diferentes. Aun así, en un Odoo caso, algunas operaciones son mucho más complejas, y es
siempre bueno de tener un brujo disponible que hace "la cosa correcta." Cuándo utilizando
tales brujos, ser seguro para comprobar el código de fuente para cualquier uso posible del
modelo_activo / activo_id / activo_ids llaves del contexto, en qué caso,
necesitas pasar un contexto hecho de encargo (ve la Llamada un método con una receta de
contexto modificada anteriormente para cómo para hacer este).
Redirecting El usuario
El método en paso 2 no regresa cualquier cosa. Esto causará el diálogo de brujo para ser
cerrado después de la acción está actuada. Otra posibilidad es para tener el método regresa
un diccionario con los campos de un ir.Acción. En este caso, elw eb el cliente procesará la
acción como si una entrada de carta había sido clicked encima por el usuario. Para caso, si
quisimos mostrar la vista de forma del miembro quién ha justo tomó prestado los libros,
podríamos haber escrito el siguientes:
@api.multi
def El registro_toma
prestado(self): para
brujo en self:
Brujo = de
miembro.Miembro_id reserva
= brujo.Libro_ids
miembro.Toma
prestado_libros(libros)
Miembro_ids = self.mapped(
Soyrescoldo_id').ids Acción = {
'Tipo': 'ir.Acción.Ventana_de
acto', 'nombre': 'Prestatario',
ess_modelo':
'biblioteca.Miembro',
'Ámbito': [('id', '=', miembro_ids)],
'modo_de vista': 'forma,árbol',
}
Acción de regreso
Esto construye una lista de miembros quién ha tomado prestado reserva de este brujo (en
práctica, sólo habrá uno tal miembro, cuándo el brujo se apellida de la interfaz de usuario)
y crea un dynamic acción, el cual muestra los miembros con el especificados IDs.
137
Desarrollo de Lado de Servidor adelantado Técnicas
Este truco puede ser extendido por habiendo un brujo (con varios pasos para ser actuados uno
tras otro), o dependiendo de algún conditiencima de los pasos de preceder, por proporcionar un
botón Próximo que llamadas un método definido en el brujo. Este método actuará el paso (quizás
utilizando un campo escondido y almacenando el número de paso actual), actualización algunos
campos en el brujo, y regresar una acción then voluntad redisplay el mismo brujo actualizado y
prepararse para el paso próximo.
Preparándose
Si quieres seguir la receta, marca seguro tú have el mi_módulo addon de Capítulo 3,
Creando Odoo Módulos, con el Escribir un brujo para guiar los cambios de la receta de
usuario aplicaron.
Finalmente, necesitarás definir una vista, una acción, y una entrada de carta para el
brujo. Esto queda como un ejercicio.
138
Capítulo 6
Cómo trabaja…
Un onchange usos de método the @api.onchange decorator, El cual está pasado los
nombres de los campos que cambio y así provocará la llamada al método. En nuestro
caso, decimos que siempre que miembro_id está modificado en la interfaz de usuario,
el método se tiene que apellidar.
En el cuerpo del method, buscamos los libros actualmente tomados prestado por el
miembro, y utilizamos una asignación de atributo para actualizar el libro_ids atributo
del brujo.
Allí ha más…
El uso básico de onchange los métodos es para computar valores nuevos para campos
cuándo algunos otros campos están cambiados en la interfaz de usuario, cuando
hemos visto en la receta.
Dentro del body del método, consigues acceso a los campos mostraron en la vista actual del
registro, pero no necesariamente todos los campos del modelo. Esto es porque onchange los
métodos se pueden apellidar mientras el registro está siendo creado en la interfaz de usuario
antes de que está almacenado en la base de datos! Dentro de un onchange método, self es
en un estado especial, denotado por el hecho que self.id no es un entero, pero un caso de
openerp.Modelos.NewId . Por tanto, no tienes que hacer cualesquier cambios a la base de datos
en un onchange método, becautiliza el usuario puede acabar cancelar la creación del registro, el
cual no rodaría atrás cualesquier cambios hicieron
Por el onchanges llamó durante la edición. Para comprobar para este, puedes utilizar
self.env.in_ onchange() y self.env.in_borrador() —los regresos anteriores Ciertos
si el contexto actual de ejecución es un onchange método y los regresos últimos Ciertos si
self no es todavía cometido a la base de datos.
139
Desarrollo de Lado de Servidor adelantado Técnicas
Además, onchange los métodos pueden regresar un diccionario de Pitón. Este diccionario
puede tener las llaves siguientes:
fAviso: El valor tiene que ser otro diccionario con el títulode llavesy
mensajerespectivamente conteniendo el título y el contenido de una caja de
diálogo, el cual será mostrado cuándo el onchange el método está corrido. Esto
somos eful para dibujar la atención del usuario a incongruencias o a problemas
potenciales.
fÁmbito: El valor tiene que ser otros nombres de campo de mapeo de diccionario a
ámbitos. Estoes útil cuándo quieres cambiar el ámbito de un Un2mucho campo
dependiendo de el valor de otro campo.
Para caso, supone tenemos un valor fijo puesto para fecha_de regreso_esperado
en nuestra biblioteca.Libro.Modelo de préstamo, y queremos mostrar un aviso
cuándo un miembro tiene algunos reserva aquello es tarde. También queremos restringir
la elección de libros a tél unos actualmente tomados prestado por el usuario. Podemos
reescribir el onchange método como sigue:
@api.onchange(
Soyrescoldo_id') def
onchange_miembro(self):
Préstamo =
self.env['Biblioteca.Libro.Préstamo'
] presta = préstamo.Búsqueda(
[( Estate', '=', 'actual'), (
soyrescoldo_id', '=',
self.member_id.id)]
)
self.Libro_ids =
préstamos.mapped('Libro_id') resultado
= {
'Ámbito': {'libro_ids': [
('id', 'en', self.Libro_ids.ids)]
}
}
Ámbito_tardío = [
('id', 'en', préstamos.ids),
('Fecha_de regreso_esperado', '<', campos.Fecha.Hoy())
]
Préstamos_de préstamos =
tardíos.Búsqueda(ámbito_tardío) si
préstamos_tardíos:
Mensaje = ('Advertir el miembro que el siguiente
' 'los libros son tarde:\n')
Títulos =
préstamos_tardíos.mapped('book_id.name')
Resultado['aviso'] = {
'Título': 'Tarde reserva',
Soyessage': mensaje + '\n'.Une(títulos)
}
Resultado de regreso
140
Capítulo 6
Preparándose
Nosotros reutilización los encuadres de la receta de preceder, Escribe onchange métodos.
La acción tendrá lugar en un método nuevo de biblioteca.El miembro llamó
regresar_todos los _libros(self).
141
Desarrollo de Lado de Servidor adelantado Técnicas
Si isinstance(val, tuple):
valor[nombre] = val[0]
Valores.Actualización(valor)
7. Crear el brujo:
Brujo = récord.Crea(valores)
Cómo trabaja…
Para una explicación de paso 1 para dar un paso 3, complacer referir a la receta Crea
registros nuevos en
Capítulo 5, Desarrollo de Lado de Servidor Básico.
de validez nueva.
Paso 6 actualizaciones nuestro diccionario de valores inicial con los valores computó por el
onchange. Procesamos los valores que corresponden a Muchos2un campos a sólo mantener
el id. Para hacer tan, aprovechamos el hecho que estos campos son sólo aquellos cuyo valor
está regresado como tuple.
Allí ha más…
Si necesitas llamar un onchange método después de modificar un campo, el código es
igual. Justo necesitas conseguir un diccionario para los valores del registro, los cuales
pueden ser obtenidos by utilizando valores = dict(récord._cache) Después de
modificar el campo.
Ve también
fElCrear Actualización y registrosnuevos valores de recordset recetasde
registros enCapítulo 5,Desarrollo de Lado de Servidor Básico
Preparándose
Dejado portuario el siguiente addon código de módulo desarrollado con el tradicional API:
Libro de biblioteca_de la
clase(orm.Modelo): _nombre
= 'biblioteca.Libro'
_columnas = {
'Nombre': campos.char('Nombre', requerido=Cierto),
143
Desarrollo de Lado de Servidor adelantado
Techniques
Miembro de biblioteca_de la
clase(orm.Modelo): _nombre =
'biblioteca.Miembro'
_Hereda = { ess.Socio': 'socio_id'}
_Columnas = {
'Socio_id': campos.Muchos2un( ess.Socio',
'Socio',
requerido=Cier
to),
'Préstamo_duration': campos.Entero('duración de
Préstamo',
requerido=Cierto
),
'Inicio_de fecha': campos.Fecha( soyrescoldo
desde entonces'), 'fin_de fecha':
campos.Fecha('fecha de Expiración'), 'número':
campos.char('Número', requerido=Cierto),
}
_defaults = {
'Duración_de
préstamo': 10,
}
_('Error!'),
144
Capítulo 6
val = self._Prepara_préstamo(
cr, uid, miembro, libro_id, contexto=de contexto
)
Préstamo_id = préstamo_obj.Crea(cr,
uid, val, contexto=de contexto)
_Columnas = {
'Libro_id': campos.Muchos2un('biblioteca.Libro',
requerido=Cierto), soyrescoldo_id':
campos.Muchos2un('biblioteca.Miembro',
Requerido=Cierto),
estate': campos.Selección([('actual', 'Actual'),
('Hecho', 'Hecho')],
estate',
requerido=Cierto),
'Fecha': campos.Fecha('fecha de Préstamo',
requerido=Cierto), 'duración':
campos.Entero('Duración'), 'la fecha_prevista':
campos.Función(
fnct=_Computa_la
fecha_prevista,
tipo='fecha', la
tienda=Cierta,
Cuerda='Previsto para'),
}
145
Desarrollo de Lado de Servidor adelantado Técnicas
retFecha de urna.Hoy().strftime(FECHA_FMT)
_defaults = { 'Duración':
15, 'fecha':
_default_fecha,
}
3. Modificar las definiciones de clase al nuevos API clases de base, y rebautizar las
clases para utilizar CamelCase:
Clase LibraryBook(modelos.Modelo):
_nombre = 'biblioteca.Libro'
Clase
LibraryMember(modelos.Modelo)
: _nombre =
'biblioteca.Miembro'
_Hereda = { ess.Socio': 'socio_id'}
Clase LibraryBookLoan(modelos.Modelo):
_nombre =
'biblioteca.Libro.Préstamo'
146
Capítulo 6
Campos = de nombre.Char('Nombre',
requerido=Cierto) autor_ids =
campo.Muchos2muchos( ess.Socio')
Libro_id = campos.Muchos2un('biblioteca.Libro',
requerido=Cierto) miembro_id =
campos.Muchos2un('biblioteca.Miembro',
Requerido=Cierto)
Campos = estatales.Selección([('actual', 'Actual'),
('hecho', 'Hecho')],
estate',
requerido=Cierto)
Campos = de fecha.Fecha('fecha de Préstamo',
requerido=Cierto,
default=_default_fecha)
147
Desarrollo de Lado de Servidor adelantado
Techniques
computa='_computar_la fecha_prevista',
La
tienda=Cierta,
cuerda='Previsto
para'
)
148
Capítulo 6
Si len(self) != 1:
Levanta excepciones.UserError(
_(' Está prohibido para prestar los mismos
libros ' 'a miembros múltiples.')
)
Modelo_de préstamo = self.env['Biblioteca.Libro.Préstamo']
Para libro en
self.env['Biblioteca.Libro'].Explora(libro_ids): val
= self._Prepara_préstamo(libro)
Modelo = de préstamo_del
préstamo.Crea(val) @api.multi
def _Prepara_préstamo(self,
libro) self.Asegura_un()
Regreso {'libro_id': book.id,
soyrescoldo_id': self.id,
'duración': self.Duración_de
préstamo}
149
Desarrollo de Lado de Servidor adelantado Técnicas
Cómo trabaja
Paso 1 cambios las importaciones. El viejo API vidas en el openerp.osv Paquete, el cual
cambiamos
Para utilizar openerp.Modelos, openerp.Campos, openerp.api, y openerp.Excepciones .
Nosotros altan gota la importación de DEFAULT_FORMATO_de FECHA_del SERVIDOR, porque
utilizaremos el helper métodos en campos.Fecha para actuar datetime / conversiones de
cuerda.
Paso 2 cambios las clases de base de los modelos. Dependiendo de la edad del código
estás emigrando, puedes need para reemplazar el siguiente:
f osv.osv, osv.Modelo u orm.Modelo con modelos.Modelo.
fosv.osv_Memoria,osv.TransientModel, o
orm.TransientModelCon modelos.TransientModel
Los atributos de clase habituales como _nombre, _orden, _hereda, _hereda, y tan en
are sin cambios.
Pasos 3 a 8 trata la migración de las definiciones del campo. El _campo de mapeo de
diccionarios de columnas nombres a definiciones de campo en el viejos API está emigrado a
atributos de clase.
Cuándo haciendo tan, no olvida para sacar las comas que siguen cada
definición de campo en el diccionario, otherwise el valor de atributo será un 1 -
elemento tuple, y conseguirás errores. También consigues una línea de
registro del aviso para estos.
Campo1 = campos.Char('Campo1')
Campo2 = campos.Entero('Campo2', default=42)
150
Capítulo 6
El cambio más grande es para functien campos. El viejo API campos de usos.La función
definida con un parámetro de tipo que da el tipo de la columna. El nuevo API utiliza un campo
del tipo esperado, definido con un computar parámetro, el cual da el método utilizó para
computar el campo:
_Columnas = {
'field3': campos.Función(
_computa_campo3, arg=Ninguno,
fnct_inv=_campo_de tienda3,
fnct_inv_arg=Ninguno, tipo='char',
fnct_campo=_de búsqueda_de la
multi=palabra clave
),
}
Campo3 = campos.Char('Field1'
computar='_computar_campo3
', inverse='_campo_de
tienda3',
búsqueda='_campo_de
búsqueda3', la
tienda=booleana)
151
Desarrollo de Lado de Servidor adelantado Técnicas
152
7
Depuración y
Testaje
automatizado
En este capítulo, cubriremos los temas siguientes:
Introducción
Vimos en Capítulo 5, Lado de Servidor Básico Lógica Empresarial, cómo para escribir
métodos de modelo para implementar la lógica de nuestro módulo. Aun así, un
desarrollador responsable no sólo escribe la implementación pero también proporciona
automated pruebas para esta implementación. Las recetas en este capítulo cubren la
depuración y probando de métodos de lado del servidor.
Produciendo registros de servidor
para ayudar depurar métodos
Registros de servidor son útiles cuándo intentando representar fuera qué ha sido pasando
en runtime before un accidente. También pueden ser añadidos para proporcionar
información adicional cuándo depurando un asunto. Estos espectáculos de receta cómo para
añadir logging a un método de existir.
153
Depuración y Testaje Automatizado
Preparándose
Añadiremos algunos logging declaraciones a tél siguiendo método, el cual salva los niveles
accionarios de productos a un archivo:
De os.Importación de camino une
De openerp modelos de importación, api,
las excepciones EXPORTA_DIR =
'/srv/exporta'
Clase
ProductProduct(modelos.Modelo):
_hereda = 'producto.Producto'
@api.Modelo
def Nivel_accionario_portuarioex(self,
ubicación_accionaria): productos =
self.Con_contexto(
Ubicación=stock_location.id ).Búsqueda([])
Productos = de
productos.Filtrado('qty_disponible') fname =
unir(EXPORTACIONES_DIR, estock_nivel.txt')
Prueba:
Con abierto(fname, 'w') cuando
fobj: para prod en
products:
fobj.Escribe('%s\t%f\n' % (prod.name,
prod.qty_Disponible
))
Excepto IOError:
Levanta excepciones.UserError('Incapaz de salvar
archivo')
154
Capítulo 7
_logger.Depura('%d productos en la
ubicación', len(productos))
fname = Une(EXPORTACIONES_DIR,
estock_nivel.txt') Prueba:
Con abierto(fname, 'w') cuando
fobj: para prod en
productos:
fobj.Escribe('%s\t%f\n' %
(prod.name,
prod.qty_Disponible))
Excepto IOError:
_logger.Excepción(
'Error mientras writing a %s en
%s', estock_nivel.txt',
EXPORTACIONES_DIR)
Levanta excepciones.UserError('Incapaz de
salvar
archivo')
Cómo trabaja…
Paso 1 importaciones el módulo logging de la Pitón biblioteca estándar. Odoo Utiliza este
módulo para dirigir sus registros.
Paso 2 instala un logger fo el módulo de Pitón. Utilizamos un modismo común en Odoo por
utilizar el __nombre__ variable automática para el logger nombre y llamando el logger
_logger.
Paso 3 usos el logger para producir mensajes de registro. Métodos disponibles para este es
(por registro creciente level) depura, info, aviso, error, y crítico . Todos estos métodos
aceptan un mensaje en qué te puede tener % sustituciones y argumentos adicionales para
ser insertados en el mensaje. Tienes que no la % sustitución tú; el logging el módulo es
listo enough para actuar esta operación sólo si el registro tiene que ser producido. Si estás
corriendo con nivel de registro de INFO , entonces DEPURAR los registros evitarán hacer la
sustitución.
Otro método útil mostrado en la receta es _logger.Excepción(), los cuales pueden ser
utilizados en un exceptuarión handler. El mensaje será logged con un nivel de ERROR y el
stack el rastro es también imprimido en el registro de aplicación.
Allí ha más…
Puedes controlar el logging nivel de la aplicación de la línea de orden o del archivo
de configuración. Hay dos maneras principales de hacer este:
fPara controlar el nivel de registro globalmente, puedes utilizar el --registro-
opciónde línea de orden de nivel.Ve Capítulo 2, Dirigiendo Odoo Casos de
Servidor, para más información.
fPara poner el nivel de registro para un dado logger, puedes utilizar--registro-
handler=prefijo:nivel.En este caso, el prefijo es una pieza del camino del
logger nombre, y el nivel es uno
De DEPURAR , INFO, AVISO, ERROR, o CRÍTICO . Si omites prefijo, entonces
pusiste el default nivel para todo loggers. Para caso, para poner el logging nivel de
mi_mo dule loggers para DEPURAR y mantener el default nivel de registro para el
otro addons, puedes empezar Odoo así:
$ Pitón odoo.py --registro-handler=openerp.addons.my_módulo:DEPURA
Preparándose
Nosotros reutilización el mismo código cuando en la receta anterior para producir registros
de servidor para ayudar depurar métodos; esto habilita el producto.Modelo de producto
para añadir un método nuevo. Suponemos que tienes un caso con el addon instalado
disponible. En la receta, esperamos que tienes un Odoo archivo de configuración para este
caso proyecto llamado.conf.
Cómo trabaja…
Paso 1 usos odoo.py pelar para empezar el Odoo concha. Toda la orden habitual
argumentos de línea son disponibles. Utilizamos -c para especificar un archivo de
configuración del proyecto y --registro-nivelar para reducir la verbosidad de los registros.
Cuándo depurando, puedes querer tener un logging nivel de DEPURAR sólo para algún
concreto addons.
Antes de proporcionar tú con una orden de Pitón-tachar puntual, odoo.py la concha
empieza un Odoo caso que no escucha en la red e inicializa algunos variables globales, el
cual are mencionado en la producción:
fenvEs un entorno conectó a la base de datos especificada en la línea de orden o
en el archivo de configuración.
fopenerpEs elopenerpel paquete importado para ti. Consigues acceso a
todos los módulosde Pitón dentro de aquel paquete así que puedes hacer qué
quieres.
fselfEs un recordset de res.Los usuarios quecontienen un registro solo
para el Odoo super usuario(Administrador), el cual está enlazado al entorno env.
Paso 3 y 4 uso env para conseguir un vacío recordset y encontrar un registro por XML ID.
Paso 5 calls el método en el producto.Producto recordset. Estas operaciones son
idénticas a qué utilizarías dentro de un método, con la diferencia pequeña que utilizamos
env y no self. env (A pesar de que podríamos tener ambos tan son idénticos). Ve
Capítulo 5, Básico Server Desarrollo de Lado, para más información en qué es disponible.
Paso 6 comete la transacción de base de datos. Esto no es estrictamente necesario aquí
porque no modificamos cualquier registro en la base de datos, pero si habíamos hecho tan
y quiso estos cambios para persistir, esto es necesario—cuándo utilizas Odoo a través de
la interfaz de web,
Cada RPC carreras de llamada en su transacción de base de datos propia y Odoo dirige estos
para ti. Cuándo corriendo en el modo de concha, esto ya no pasa y tienes que llamar
env.cr.Comete() o env.cr.rollba ck() Tú. Otherwise, cuándo sales la concha, cualquier
transacción en progreso es automáticamente rodado atrás. Cuándo probando, esto es bien,
pero si utilizas la concha, por ejemplo, a guión la configuración de un caso, no olvida para
cometer vuestro trabajo!
158
Capítulo 7
Preparándose
Seremos reusing la exportación_nivel_accionario() el método mostrado en las dos recetas
anteriores. Ser seguro para tener una copia a mano.
ubicación=stock_location.id
).Búsqueda([])
fname = Une(EXPORTACIONES_DIR, estock_nivel.txt')
Prueba:
Con abierto(fname, 'w') cuando fobj:
Para prod en
productos.Filtrado('qty_disponible'):
fobj.Escribe('%s\t%f\n' % (
prod.name, prod.qty_Disponible))
Excepto IOError:
Levanta excepciones.UserError('Incapaz de salvar
archivo')
159
Depuración y Testaje Automatizado
3. En el (Pdb) puntual, asunto el args (atajo un) orden para conseguir los valores de
los argumentos pasaron al método:
(Pdb) Un
self = Producto.Producto() stock_de
ubicación = accionaria.Ubicación(12,)
ubicación=stock_location.id
).Búsqueda([])
fname = Une(EXPORTACIONES_DIR,
estock_nivel.txt') Prueba:
Con abierto(fname, 'w') cuando fobj:
Para prod en
productos.Filtrado('qty_disponible'):
fobj.Escribe('%s\t%f\n' % (prod.name,
prod.qty_Disponible))
5. Introducir la orden próxima tres tiempo para andar a través de las primeras líneas
del método. También puedes utilizar n, el cual es un atajo :
(Pdb) Luego
> /Recetario/de
casa/nivel_accionario/models.py(17)exporta_nivel_accionario()
->
Ubicación=stock_location.id
(Pdb) n
> /Recetario/de
casa/nivel_accionario/models.py(18)exporta_nivel_accionario()
-> ).Búsqueda([])
(Pdb) n
> /Recetario/de
casa/nivel_accionario/models.py(19)exporta_nivel_accionario()
-> fname = une(EXPORTACIONES_DIR, estock_nivel.txt')
(Pdb) n
> /Casa/cookbook/nivel_accionario/models.py(20)exporta_nivel_a
ccionario() -> probar:
6. Uso el p orden para mostrar los valores de los productos y fname variables:
(Pdb) p Productos
Producto.Producto(67, 14, 12, 6, 7, 8, 17, 18, 13, 55, 15, 10, 11,
64, 31, 23, 42, 30, 29, 53, 56, 63, 62, 43, 61, 35, 51, 26, 24, 25,
39, 40, 45, 34, 32, 33, 57, 65, 28, 27, 38, 16, 19, 49, 5, 36, 37,
44, 21, 22, 20, 59, 52, 66, 58, 54, 60, 46, 41, 47, 48, 50, 3,
160
Capítulo 7
2, 1, 4)
(Pdb) p fname
'/srv/Exporta/nivel_accionario.txt'
Cómo trabaja…
En paso 1, nosotros hardcode un punto de rotura en el código de fuente del method
por llamar el rastro_de conjunto() método del pdb módulo de la Pitón
biblioteca estándar. Cuándo este método está ejecutado, el flujo normal de las
parones de programa, y consigues un (Pdb) incita en qué te puede introducir pdb
órdenes.
161
Depuración y Testaje Automatizado
Pasos 3 a 8 uso varios pdb órdenes para dar un paso a través de la ejecución del método. Aquí
es un resumen de las órdenes principales de pdb . La mayoría de ellos es también disponible
utilizando la primera letra como atajo. Indicamos esto por habiendo las letras opcionales entre
paréntesis:
162
Capítulo 7
Allí ha más…
En la receta, insertamos un pdb.Rastro_de conjunto() declaración para romper a pdb
. También podemos empezar pdb directamente de dentro del Odoo concha, el cual es muy
útil cuándo puedes no fácilmente modificar el código del proyecto por utilizar
pdb.runcall(). Esta función toma un method como el primer argumento y los argumentos
para pasar a la función como los argumentos próximos. Tan dentro del Odoo concha, tú
esto:
>>> Importación pdb
>>> Producto = env['producto.Producto']
>>> Stock_de ubicación = env.ref( Estock.Stock_de ubicación_accionaria')
>>> pdb.runcall(Producto.export_Nivel_accionario, stock_de
ubicación) > /recetario/de
casa/odoo/openerp/api.py(235)wrapper()
-> Si '_ids' en self.__dict__:
(Pdb)
163
Depuración y Testaje Automatizado
> /Recetario/de
casa/nivel_accionario/models.py(15)nivel_accionario_portuarioe
x() -> productos = self.Con_contexto(
(Pdb)
Ve también
f Para la documentación llena de pdb , refiere a https://d ocs.python.org/2.7/
Biblioteca/pdb.html
Preparándose
Esta receta supone tienes un caso a punto con el código parat él mi_módulo de módulo
definido en Capítulo 3, Creando Odoo Módulos, y el código del Definir métodos de Modelo y
utilizar el API decorators receta en Capítulo 5, Desarrollo de Lado de Servidor Básico.
164
Capítulo 7
How Trabaja…
El YAML archivos estamos utilizando aquí es el mismo tan los utilizaron para cargar archivos
de dato
(Ve Capítulo 9, Dato de Módulo), exceptúa que están incluidos en la llave de prueba del
__openerp__.py Más que en la llave de dato. Añadimos que llave en paso 1. Son por tanto
procesados sólo cuándo corriendo las pruebas (ve el Servidor de Correr receta de Pruebas en
este capítulo).
Paso 3 añade una descripción en la parte superior del archivo de prueba en un YAML nodo
de prueba. Mente la sangría del texto, después del - delimitando un nodo. Esta descripción
será imprimida en el registro de prueba (en nivel de registro DEPURA).
Paso 4 usos un !Contexto YAML nodo para cambiar elev aluation el contexto utilizado en
la prueba.
El uso más común de este nodo es para modificar el usuario utilizó para correr la prueba del
administrador a alguien más por asignar una cuerda que contiene el XML ID del usuario a uid .
Paso 5 crea algún dato de prueba utilizando un !Récord YAML nodo. El YAML attributes,
entre tirantes, dar el nombre del modelo para ser utilizado y el XML ID para utilizar para el
registro nuevo.
166
Capítulo 7
YAML Sintaxis
Toma nota del | carácter al final del !Nodo de pitón. Suele denotar un
nodo de texto literal, en qué whitespace no es processed. Necesitas
esto para código de Pitón donde espaciando es significativo.
Dentro del bloque de Pitón, también puedes utilizar las variables siguientes:
Allí ha más…
Cuando !Afirma no es conveniente para escribir controles, para caso, si no tienes un XML
ID para que así conste quieres control, puedes utilizar un !Bloque de pitón y el afirmar
palabra clave de Pitón. Nosotros could también reescribir el último control de la receta así:
-
Intenta llamar estado_de cambio para hacer borrador de libro,
control esto no tiene ningún efecto
-
!Modelo {de pitón: biblioteca.Libro, id:
testbook}: | self.Estado_de
cambio('borrador')
Afirma self.Estatal == 'disponible', 'incorrecto state %s' %
self.Estatal
167
Depuración y Testaje Automatizado
Preparándose
Esta receta supone tienes un caso a punto con el código para el mi_módulo de módulo
definido en Capítulo 3, Creando Odoo Módulos, y el código de Capítulo 5, Desarrollo de Lado
de Servidor Básico, en la receta Define Modelo methods y utilizar el API decorators.
Cómo trabaja…
Creamos una Pitón subpackage en nuestro módulo llamó pruebas y añadir un módulo
de prueba con un nombre que empieza con te st_. Esto es la convención utilizado por
Odoo para descubrimiento de prueba.
En este archivo, importamos la clase de prueba de la base, TransactionCase, de
openerp.Prueba.Común . Esta clase extiende el unittest.TestCase Clase de la Pitón
biblioteca estándar para hacer él propio para nosotrose en Odoo:
fElsetUp()el método inicializa elself.envAtributo, el cual te puede utilizar para
actuarlas operaciones habituales (ve las recetas en Capítulo 5, Desarrollo de Lado de
Servidor Básico)
fEltearDown()corros de método respaldan la transacción de base de datos de
modo que las pruebas estáncorridas en aislamiento
Las pruebas están definidas en los métodos nombraron con un prefijo de prueba. El
corredor de prueba correrá entonces uno tras otro con una llamada a setUp() antes de
cada método de prueba y una llamada a tearDown() después de que cada cual. Dentro
del método, puedes utilizar toda la aserción habitual métodos de unittest.TestCase . Aquí es
el más generalmente utilizó unos:
La prueba tendrá éxito si la excepción pasó a assertRaises está generado por el bloque de
código; otherwise falle.
Para más información encima pruebas de unidad en Pitón, complacer referir a la biblioteca
estándar documentation en
https://docs.python.org/2.7/library/unittest.html#prueba-casos.
Allí ha más…
El módulo openerp.Prueba.Común define varias clases que puede ser utilizado tan
clases de base para casos de prueba:
fTransactionCase: Cada cual me pruebothod está corrido independientemente y la
transacciónde base de datos está rodada atrás después de que cada cual. Esto
significa que cualesquier cambios hicieron en uno prueba el método no es visto por
los otros métodos de prueba. Puedes utilizar el tradicional setUp() y tearDown()
métodos para actuar inicial de pruebaization y cleanup.
fSingleTransactionCase: Todos los métodos de pruebas están corridos en la
misma transacción,el cual es sólo rodado atrás después del último método. Si
necesitas actuar inicialización y cleanup para el caso de prueba, necesitas extender
el setUpClass() y tearDownClass() métodos. No olvida para decorar estos con
@classmethod , o conseguirás errores extraños cuándo llamando el super()
implementación.
fSavePointCase: Es una extensiónSingleTransactionCaseaquello
creauna base de datos SAVEPOINT antes de correr métodos de prueba y
restaurándoles después de que la prueba está corrida. El efecto neto es que puedes
correr vuestras pruebas en aislamiento cuando con TransactionCase sin teniendo
que pagar el precio de un costoso setUp() el método que recrea todo el dato entre
todas las pruebas—el initialization está actuado en setUpClass() y rodamos atrás
la transacción al estado salvado después de cada prueba.
Preparándose
Seremos reusing las pruebas para el mi_módulo de módulo de uno de las recetas
anteriores. Necesitarás un caso con el addon instalado. En esta receta, suponemos que el
caso configuration el archivo es en proyecto.cfg.
Cómo trabaja…
La parte clave en este recipe es el --prueba-habilitar orden-bandera de línea que dice
Odoo para correr las pruebas. El --parón-después de que-init la bandera parará el
caso después de las pruebas ha corrido y -u actualizará el módulo especificado. Cuándo
una actualización (o instalar) está actuado en modo de prueba, todo el affected addon
módulos' las pruebas están corridas (esto incluye dependencias automáticamente
dependencias instaladas o inversas automáticamente actualizaron; ver la receta Instala y
upgrade local addon módulos en Capítulo 2, Dirigiendo Odoo Casos de Servidor, para más
información en este).
Puedes correr las pruebas que utilizan la configuración de registro siguiente: --registro-
error=de nivel --registro-handler=openerp.Módulos.Cargando:INFO. Esto
deja para tener información sobre las varias pruebas' archivos para ser procesados pero
no los detalles de los registros del operationes, sólo los mensajes de error.
Allí ha más…
El principal drawback de de este modo de correr las pruebas es que tienes que correr todas
las pruebas para un dados addon módulo, incluso si sabes que ellos todos pasan pero el
estás intentando fijar, y también tienes que update el addon (cuáles pueden ser en él una
operación costosa).
172
Capítulo 7
Esto correrá sólo las pruebas definieron en aquel archivo, y trabaja también si especificas
un archivo que contiene YAML pruebas. Él también skip actualizando el módulo, así que
no trabaje si has changed la estructura de modelo por añadir campos nuevos o modificó
los archivos de dato del addon desde entonces la última vez el módulo estuvo actualizado.
Preparándose
Para utilizar esta receta, necesitas tener un público GitHub repositorio con vuestros módulos. En
el tiempo de escribir, el OCA las herramientas esperan que este repositorio contiene varios
addons en subdirectorios.
173
Depuración y Testaje Automatizado
174
Chapter 7
175
Depuración y Testaje Automatizado
177
Depuración y Testaje Automatizado
Cómo trabaja…
Cuándo habilitas Travis CI en un repositorio, Travis registra un gancho en GitHub. Por
default, el gancho provocará un Travis CI complexión para cada empujón a una rama del
repository y para cada petición de atracción. Peticiones de atracción están construidas en
un provisionales fusionar del PR, para asegurar que el fusionó las ramas pasan las pruebas.
El Travis CI archivo de configuración propuso aquí es bastante adelantado y muy cercano al
encontrado en los archivos_de muestra subdirectory del maintainer-calidad -las
herramientas te proyectan puede ver en https://github.com/oca/maintainer-
quality-tools ( sacamos el transifex la configuración utilizó para dirigir traducciones de
módulo). Aquí es una explicación del personalizó secciones en el archivo:
faddons: Esto tiene nada para hacer con Odoo addon módulos. Está utilizado para
preguntar Travis parainstalar algunos Ubuntu los paquetes que utilizan paquetes
de distribución en el entorno de testaje. Esto nos salvo de enparar paquetes de Pitón
como pitón-lxml de fuente, el cual toma mucho tiempo.
fenv: Esta sección define variables de entorno y la matriz de complexión. El
maintainerherramientas de calidad utilizan estas variables de entorno para saber
qué para probar, y correrá each env línea en una carrera de prueba separada:
VERSIÓN: Esto es el Odoo versión para probar en contra.
CONTROL_de PELUSA: Uso 0 para una complexión sin escama8 o
Pylint pruebas, y 1 otherwise. En la matriz, pusimos la primera
complexión para actuar el control de pelusa, cuando esto esf ast y
queremos retroalimentación rápida si los estándares de codificación no
son conocidos o si el linter encuentra errores.
PRUEBAS: Uso 0 para una complexión en qué las pruebas de módulo no
son corridas; otherwise uso 1.
ODOO_REPO: Esto es el GitHub repositorio para Odoo para probar contra
when las PRUEBAS es 1. En la receta, instalamos una complexión
contra ambos el oficial https://github.com/odoo/odoo
repositorio y el comunitario backports https de
repositorio://github.com/OCA/OCB. Si unset,
Sólo el repositorio oficial está utilizado.
178
8
Backend
Vistas
En este capítulo, cubriremos los temas siguientes:
fffffff
f
f
f
f
f
f
f
f
f
f
n de ventana
A
ñ Teniendo una acción abre una vista concreta
a Añadiendo contenido y widgets a una
di
vista de forma que Añade perotoneladas
e
n a formas
d Pasando parámetros a formas y acciones: Contexto
o
u Definiendo filtros oficialmente listas: Ámbito
n Vistas de
el
e Búsqueda de
m vistas de lista
e
n Cambiando existiendo vistas:
t Documento de herencia de la Vista-
o
formas de estilo
d
e Elementos de forma dinámica que
c utilizan attrs Embedded vistas
a
rt Kanban views
a Espectáculo kanban tarjetas en columnas según su
y
a Calendario estatal y gantt vistas
c Graph Y el pivote ve
ci
ó QWeb informes
179
Backend Vistas
Durante este capítulo, supondremos que tienes una base de datos con la base addon
instalado y un empty Odoo addon módulo donde añades XML código de las recetas a un
archivo de dato referenced en el addon es manifiesta. Refiere a Capítulo 3, Creando Odoo
Módulos para cómo para activar cambios en vuestro addon.
Introducción
Este capítulo cubre todo el UI elementos tusuarios de sombrero están afrontados con
cuándo utilizan cualquier cosa otro que la parte de sitio web de Odoo. Históricamente, esto
básicamente era todo de OpenERP, tan también en un Odoo contexto, es a menudo justo
referido a como el cliente de web. Para ser más concreto, llamaremos este the backend
como opposed al sitio web frontend.
Contexto="{'default_cliente':
límite}" Cierto="80" />
180
Capítulo 8
Costumbre="de carta_del padre_toplevel"
Nombre="Esto aparecerá en la barra izquierda" />
Si nosotros ahora upgrade el módulo, veremos una carta de nivel superior que abre un sub
carta en la barra de carta izquierda. Clicking En aquel elemento de carta abrirá una lista de
todos los clientes.
Cómo trabaja...
El primer elemento de XML, ventana_de acto, declara una acción de ventana para
mostrar una vista de lista con todos los clientes. Utilizamos los atributos más
importantes:
f Nombre: para ser utilizado como el título para las vistas abrió por la acción.
fres_Modelo: Esto es el modelo para ser utilizado. Estamos
utilizandores.Socio, donde Odooalmacena todos los socios y añadirresses,
incluyendo clientes.
fModo_de vista: Esto lista los tipos de vista para hacer disponible. El default el
valor es árbol,vista, haciendo disponible la lista y vistas de forma. Otras
elecciones posibles son kanban, graph, calendario, y gantt , explicó más tarde en
este chapter.
fÁmbito: Esto es opcional y te dejas para poner un filtro en los registros de ser
hechosdisponibles en las vistas. En este caso, queremos limitar los socios a sólo
los que son clientes . Explicaremos esto con más detalle en una receta dedicada
más tarde.
fContexto: Esto puede poner los valores hicieron disponibles al abrió vistas,
afectando sucomportamiento. En nuestro ejemplo, en registros nuevos queremos
la bandera de cliente default valor para ser Cierto. Esto será cubierto en más
profundidad en otra receta.
fLímite: Esto pone el default cantidad de registros que puede ser visto encima
vistas de lista. Éldefaults a 80 .
Luego creamos la jerarquía de elemento de la carta; de la carta de nivel superior al
clickable elemento de carta del fin. Los atributos más importantes para el menuitem el
elemento es:
fNombre: Esto está utilizado como el texto la exhibición de elementos de la carta. Si
vuestros enlaces de elemento de la carta a unaacción puedes dejar esto fuera,
porque en aquel caso el nombre de la acción será utilizado.
fPadre(padre_idsi utilizando elelementorécord): Esto es el XML ID
referencingla carta de padre élem. Los elementos sin padre son cartas de nivel
superior.
fAcción: Esto es el XML ID referencing la acción para apellidarse. Elementos de carta
únicasin elementos de niño son clickable, así que esta opción es sólo eficaz en
aquellos casos.
181
Backend Vistas
Para construir la carta, el cliente de web lee todos los registros de ir.ui.Carta e infiere su
jerarquía del padre_id campo. Las cartas son también filtró basado encima permisos
de usuario a modelos y grupos asignaron a cartas y acciones. Cuándo unos clics de
usuario unos hombresu elemento, su acción está ejecutada.
Allí ha más...
Acciones de ventana también apoyan un atributo de objetivo para especificar cómo la
vista es para ser presentado. Las elecciones posibles son:
f Actual: Esto es el default y abre la vista en el cliente de web principal content
área. Nuevo: Esto abre en un popup.
f inline: Esto hace la mayoría de sentido para formas. Abre una forma en el editar modo
pero tampoco con los botones estándares para editar, crea, o eliminar, ni con el Más
carta de acciones.
f
inlineview: Esto es similar a inline, pero obolígrafos en el modo leído en vez de
editar.
f
182
Capítulo 8
Ve también
Encontrarás una discusión más detallada de la XML ID referencia mecanismo en Capítulo
9, Dato de Módulo. Por ahora, justo mantener en mente que te puede poner referencias
de este modo y – muy importantly – que asuntos de orden. Si las etiquetas encima eran
inverted, el addon conteniendo este código de XML no instalaría porque menuitem
referiría a una acción desconocida.
La acción type ir.Acciones.Ventana_de acto es el más común un, pero una carta
puede referir a cualquier tipo de acción. Técnicamente, es justo igual si enlazas a una
acción de cliente, una acción de servidor, o cualquiera otro modelo definido en el
ir.Acciones.* namespace. Justo difiere en what el backend marcas fuera de la acción.
Si necesitas justo un minúsculo mordió más flexibilidad en la acción concreta para
apellidarse, mirada a las acciones de servidor que regreso una acción de ventana en vuelta.
Si necesitas flexibilidad completa en qué te presente, mirada a las acciones de cliente
(ir.Acciones.Cliente) cuáles te dejáis para tener un usuario completamente hecho de
encargo interfaz. Pero sólo hacer tan tan último recurso cuando pierdes mucho Odoo
conveniente helpers cuándo utilizándoles.
183
Backend Vistas
Ahora si abres vuestra carta y clic algún socio en la lista, tendrías que ver la forma muy
mínima justo definimos.
184
Capítulo 8
Cómo trabaja...
Este tiempo, utilizamos el código de XML genérico para cualquier tipo de récord aquello es,
el elemento récord con el requerido atribuye id y modelo . Tan más temprano, el id el
atributo es una cuerda arbitraria que tiene que ser único para vuestro addon. El atributo
de modelo refiere al nombre del modelo quieres crear. Dado que queremos crear una
vista, necesitamos crear un registro de modelo ir.ui.Vista. Dentro de este elemento,
pusiste campos cuando definidos en el modelo escogiste vía el atributo de modelo.
Para ir.ui.Vista, los campos cruciales son model y arco . El campo de modelo
contiene el modelo quieres definir una vista para, mientras el campo de arco contiene la
definición de la vista él. Vendremos a sus contenidos en a escasos mientras.
El campo de nombre, mientras no estrictamente necesario, es útil cuándo debugging problemas
con vistas, así que puestos lo a alguna cuerda que te dices lo que esta vista está pretendida para
hacer. El contenido de este campo no es mostrado al usuario, así que puedes rellenar todas las
pistas técnicas a tú que consideras sensato.
Si pusiste nada aquí, tú'll consigue un default conteniendo el nombre de modelo y tipo de
vista.
ir.Acciones.Ventana_de acto.Vista
El segundo registro definimos trabajos en unison con ventana_de acto definimos anteriormente.
Sabemos ya que por poner la vista de campo_id allí, podemos seleccionar qué vista está
utilizada para el primer modo de vista. Pero dado pusimos el modo de vista_del campo al
default árbol, forma, vista_id tendría que elegir una vista de árbol, pero queremos poner la
vista de forma, el cual viene segundo aquí.
2. Para añadir una barra de cabeza, normalmente utilizado para botones de acción
y tubería de etapa, añade dentro de la forma:
<Encabezamiento>
<Nombre de objeto="de tipo" de
botón="abre_cuerda_de entidad"
comercial="Abre socio comercial"
class="oe_punto destacado" />
</Encabezamiento>
Ahora la forma tiene que dispponer una barra superior con un botón y dos verticalmente
alineó campos.
Cómo trabaja...
Miraremos en el campo de arco del ir.ui.Modelo de vista. Aquí, todo que el usuario
ve pasa. Primero, nota que las vistas están definidas en XML ellos, así que necesitas pasar
t atribuya tipo="xml" para el campo de arco, otherwise el parser será confundido. Es
también obligatorio que vuestra definición de vista contiene bien formó XML, otherwise te
meterás en problemas cuándo cargando esta fragmento.
186
Capítulo 8
Forma
Cuándo defines una vista de forma, es obligatorio que el primer elemento dentro del campo
de arco es un elemento de forma. Este hecho está utilizado internamente para derivar el
campode tipo del registro, el cual es por qué tú no es supuesto para poner este campo.
Verás esto mucho en código de legado aun así.
El elemento de forma puede tener dos legado se atribuye, los cuales son cuerda y versión .
En las versiones anteriores de Odoo, aquellos solieron decidir en la tetale viste en el
breadcrumb y para diferenciar entre las formas escritas en pre-7.0 estilo y después, pero
ambos pueden ser considerados obsoletos por ahora. El título en el breadcrumb es ahora
inferido del nombre del modelo_consigue función, mientras la versión es tansumed para
ser 7.0 o encima.
Además de los elementos listaron luego, puedes utilizar HTML arbitrario dentro de la
etiqueta de forma. El algoritmo es que cada elemento desconocido a Odoo está considerado
HTML sencillo y sencillamente pasado a través de a el navegador. Ser prudente con aquel,
cuando el HTML rellenas puede interaccionar con el código de HTML el Odoo los elementos
generan, el cual podría distorsionar el rendering.
Encabezamiento
Este elemento es un contenedor para los elementos que tendría que ser mostrado en el
encabezamiento de una forma, el cual es rendered como barra gris. Normalmente, cuando
en este ejemplo, colocas botones de acción aquí o una barra de estado si vuestro modelo
tiene un campo estatal.
Botón
El elemento de botón suele dejar el usuario para provocar una acción. Ver la receta
siguiente
Añadiendo botones a formas para detalles.
Grupo
El elemento de grupo es Odoo medio principal para organizar contenido. Los campos
colocados dentro de un elemento de grupo es rendered con su título, y todos los campos
dentro del mismo grupo están alineados de modo que allí ha también un indicador visual
que pertenecen juntos. Puedes también nest los elementos de grupo; esto causa Odoo a
render el contuvo campos en columnas adyacentes.
En general, tendrías que utilizar este mecanismo para todos vuestros campos y únicos revert
a otros métodos
(Ve próximo) cuándo necesario.
187
Backend Vistas
Campo
Para de hecho espectáculo y manipular dato, vuestra forma tendría que contener algunos
elementos de campo. Tienen uno obligatorio attribute nombre, el cual refiere al nombre
del campo en el modelo. Tan encima, ofrecemos el usuario para editar el nombre y las
categorías del socio. Si sólo queremos mostrar uno de ellos, sin el usuario que es capaz
de editar el campo, pusimos el atributo readonly a 1 o Cierto . Este atributo de
hecho puede contener un subconjunto pequeño de código de Pitón, tan
readonly="2>1" haría el campo leído sólo demasiado. El mismo aplica al atributo
invisible, que te uso para tener el valor leído de la base de datos, pero no mostrado al
usuario. Veremos más tarde en qué situaciones queremos tener aquello.
Tienes que haber notado el atributo widget en el campo de categorías. Define cómo el
dato en el campo está supuesto para ser presentado al usuario. Cada tipo de campo tiene
su estándar widget, así que no tienes que explícitamente escoger un widget. Pero varios
tipos proporcionan multiple maneras de representación, en qué caso podrías optar para
algo más que el default. Como lista completa de disponible widgets superaría el alcance de
esta receta, tendrás que recurrir a Odoo código de fuente para probarles fuera y consultar
Capítulo 15, Desarrollo de Cliente de la Web para detalles encima cómo para hacer vuestro
propio.
Atributos generales
Encima más elementos (esto incluye grupo, campo, y botón ), puedes poner los atributos
attrs y grupos . Mientras attrs está hablado luego, el atributo de grupos te das el
possibility para mostrar algunos elementos sólo a los miembros de grupos seguros.
Sencillamente puesto el grupo XML ID (separado por comas para grupos múltiples) en el
atributo, y el elemento será escondido para todo el mundo quién no es un miembro de al
menos uno de los hombres de grupostioned.
Otras etiquetas
Hay situaciones donde te podría querer deviate de los grupos de diseño estrictos
prescribieron. Un ejemplo bueno es, si quieres el campo de nombre de un récord de ser
rendered como encabezar, la etiqueta del campo interferiría con el aspecto. En este caso, no
pone vuestro campo a un elemento de grupo, pero por ejemplo, al HTML sencillo h1
elemento. Entonces antes del h1 elemento, puesto un elemento de etiqueta con el para
atribuir puesto a vuestro nombre de campo:
<Etiqueta para="nombre" />
<h1><nombre de campo="nombre"
/></h1>
Esto será rendered con el contenido del campo como grande encabezando, pero el nombre
del campo sólo pequeño encima. Aquello es básicamente lo que el socio estándar forma
hace.
188
Capítulo 8
Si necesitas una rotura de línea dentro de un grupo, uso el newline elemento. Es siempre
vacío.
<newline />
Otro elemento útil es el footer elemento. Cuándo abres una forma como popup, esto es el
sitio bueno para colocar los botones de acción. Sea rendered como barra gris también,
análogo al elemento de encabezamiento.
Allí ha más...
Desde entonces vistas de forma son básicamente HTML con algunas extensiones, Odoo
también hace uso extenso de CSS clases. Dos muy útil unos son oe_leídos_sólo y
oe_edita_sólo – causan los elementos con estas clases aplicaron para ser visibles sólo en
modo/de vista leída o sólo en editar modo. Así que para tener la etiqueta visible sólo en
editar modo:
<Etiqueta para="clase" de nombre="oe_edita_sólo" />
Más allá, el elemento de forma puede tener los atributos crean, edita, y eliminar . Si
pusiste uno de aquellos a falso , la acción correspondiente no será disponible para esta
forma. Sin este ser explícitamente puesto, la disponibilidad de la acción está inferida de los
permisos del usuario. Nota que esto es puramente para alisar el UI; no utiliza esto para
seguridad.
Ve también
El widgets describió más temprano ya ofrecer mucha funcionalidad, pero tarde o temprano
encontrarás casos donde ellos no exactamente qué quieres. Para definir vuestro propio
widgets, refiere a Capítulo 15, Desarrollo de Cliente de la Web.
Cómo trabaja...
El atributo de tipo del botón determina el semantics de los otros campos, así que nosotros
primero mirada a los valores posibles:
fAcción: Esto hace el botón llama una acción cuando definido
enir.Acciones.*namespace. Las necesidades de atributo del nombre para
contener la base de datos de la acción id, el cual te oportunamente puede mirar
arriba con una cuerda de formato de la pitón que contiene el XML ID de la acción en
cuestión.
fObjeto: Thes llama un método del modelo actual. Elatributode nombre
contiene el nombre de lafunción. La función tendría que tener la firma
@api.multi Y actuará en el registro actualmente visto.
fworkflow: Esto envía un workflow señal al registro actual.
Elnamenecesidadesde atributo para contener el nombre de la señal. Uso el
atributo de estados para hacer el workflow los botones sólo disponibles en
estados donde ellos de hecho algo, aquello es, en estados que tiene las
transiciones provocaron por la señal en cuestión.
La cuerda attribute suele asignar el texto el usuario ve.
Allí ha más...
Uso CSS clases btn-primarios a render un botón que está destacado (actualmente
azul) y btn-default a render un botón normal. Esto es generalmente utilizado para el
cancelar botones en brujos o para ofrecer acciones secundarias en un visually manera
discreta.
La llamada con un botón de objeto de tipo puede regresar un diccionario que describe una
acción, el cual entonces será ejecutado en el lado de cliente. De este modo puedes
implementar multi brujos de pantalla o justo abrir algunos otsu registro.
Preparándose
Mientras no estrictamente necesario, esta receta será más divertida si instalas el francés
language, en caso no empezaste fuera con esta lengua en primer lugar. Consulta Capítulo 11,
Internacionalización, para cómo para hacer este. Si tienes una base de datos francesa, cambio
fr_FR a algunos otra lengua; en_EE.UU. harán para ingleses. También, clic el botón Not archived
encima uno de vuestros clientes para archivo él y verificar que este socio no aparece más en
La lista.
2. Añadir una carta que llamadas esta acción. Esto queda como un ejercicio para el lector.
Cuándo abres esta carta, las vistas aparecerán en franceses, y si creas un socio nuevo,
tenga francesa como el preselected lengua. Una menos diferencia obvia es que también
verás el socio tú deactivated más temprano.
Cómo trabaja...
El contexto dictionary está poblado de varias fuentes. Primero, algunos valores del
El registro del usuario actual (lang y tz , para la lengua del usuario y el usuario timezone) está
leído, entonces hay addons aquello añade llaves para sus propósitos propios. Más allá, el UI
añade llaves about qué modelo y qué registro somos ocupados con en el momento ( activo_id,
activo_ids, modelo_activo). Y cuando visto anteriormente, también podemos añadir
nuestras llaves propias en acciones. Aquellos están fusionados juntos y pasados a las funciones
de servidor subyacentes, y también alc lient lado UI.
Tan por poner el lang llave de contexto, forzamos la lengua de exhibición para ser
francés. Notarás que esto no cambia el entero UI lengua, el cual es porque sólo la vista de
lista que abrimos mentiras dentro del alcance de este contexto. El resto of el UI estuvo
cargado ya con otro contexto que contuvo la lengua original del usuario. Pero si abres un
registro en esta vista de lista, sea presentado en francés también, y si abres algunos
enlazaron récord en la forma o pulsar un botón que ejecuta una acción, la lengua será
propagada también.
191
Backend Vistas
Por poner default_lang, pusimos un default valor para cada récord creado dentro del
Alcance de este contexto. El patrón general es default_$fieldname: mi_default_valor, el
cual enables te para poner default valores para los socios nuevamente creados en este caso. Dado
que nuestra carta es sobre clientes, pueda haber hecho sentido a también puesto
default_cliente:
Cierto de tener el campo de Cliente comprobado por default. Pero esto es un modelo
ancho default para res.Socio en todo caso, así que esto no habría cambiado cualquier
cosa. Para campos escalares, la sintaxis para este es tan escribirías él en código de Pitón –
campos de cuerda entran cita, numera justo gusta que, y los campos booleanos son
cualquier Ciertos o Falsos . Para relational campos, la sintaxis es ligeramente más
complicada – referir a Capítulo 9, Dato de Módulo , para cómo para escribir aquellos. Nota
que el default los valores puestos en el contexto override el default los valores puestos en la
definición de modelo, así que puedes tener diferente default valores en situaciones
diferentes.
La última llave es prueba_activa , el cual tiene muy especial semantics. Para cada modelo
que tiene un campo llamó activo, Odoo automáticamente filtros fuera de los registros donde
este campo es Falso. Esto es por qué el socio donde tú unchecked este campo desaparecido
de la lista. Por poner esta llave, podemos suprimir este comportamiento.
Allí ha más...
Mientras definiendo un contexto tienes acceso a algunas variables, la mayoría de
importantes uno siendo uid, el cual evalúa al usuario actual ID. Necesitarás esto para
poner el default filtros
(Ve la receta próxima). Más allá, tú have acceso al contexto de función_hoy y la
fecha actual_variable, donde el primero es un objeto de fecha que representa la
fecha actual cuando visto del huso horario del usuario y el último la fecha actual cuando
visto en UTC, formatted tan YYYY-MM-DD. Para poner un default para un campo de
fecha a la fecha actual por default, uso fecha_actual y, para default filtros, contexto
de uso_hoy().
Más allá, puedes hacer algunos cálculos de fecha con un subconjunto de Pitón
datetime, tiempo, y relativedelta clases.
192
Capítulo 8
La misma manera que añadimos algunas llaves de contexto en nuestra acción, podemos
hacer con botones. Esto causa la función o acción las llamadas de botón para ser corridos
en el contexto dado y por ahora sabes algunos de los trucos puedes estirar de este modo.
La mayoría de elemento de forma atribuye aquello está evaluado tan la pitón también tiene
acceso al diccionario de contexto. Los atributos invisibles y readonly es tales atributos. Tan
en casos donde quieres un elemento para aparecer en una forma a veces, pero no en otro
tiempo, pusiste el atributo invisible a contexto.Consigue( soyy_llave'), y para acciones
que ventaja al caso donde el campo está supuesto para ser invisible, pusiste la llave de
contexto mi_llave: Cierto. Tal estrategia te habilitas para adaptar vuestra forma sin having
para reescribir él para ocasiones diferentes.
Puedes también puesto un contexto en campos relacionales, el cual influye cómo el campo
está cargado. Por poner la vista de forma_de las llaves_ref o vista_de árbol_ref al
XML ID de una vista, puedes seleccionar una vista concreta para este field. Esto es
necesario cuándo tienes vistas múltiples del mismo tipo para el mismo objeto. Sin esta llave
consigues la vista con el número de secuencia más bajo, el cual puede no siempre ser
deseable.
Ve también
Uno de las aplicaciones muy útiles del contexto is para poner default la búsqueda filtra tan
descrita en las vistas de Búsqueda de la receta.
193
Backend Vistas
2. Añadir una acción para los clientes quiénes son clientes o proveedores :
<Récord id="clientes_de acción_o_modelo"
de
proveedores="ir.Acciones.Ventana_d
e acto">
<Clientes de nombre="de nombre">de campo o
nombre</de campo> <de campo de
proveedores="res_modelo">res.Nombre</de campo> <de
campo de socio="ámbito">
['|', ('cliente', '=', Cierto), ( esupplier', '=',
Cierto)] </campo>
</Récord>
3. Añade cartas que llamada esta acción. Esto queda como un ejercicio para el lector.
Cómo trabaja...
La forma más sencilla de un ámbito es una lista de 3-tuples que contains un nombre de campo
del modelo en cuestión tan cuerda en el primer elemento, un operador cuando cuerda en el
segundo elemento, y el valor el campo es para ser comprobado en contra como el tercer
elemento. Esto es qué hicimos en la primera acción, y esto está interpretado cuando: Todas
aquellas condiciones tienen que aplicar a los registros somos
Interesado en. Esto de hecho es un atajo, porque los ámbitos saben los dos operadores de prefijo
& y | , dónde & es el default. Tan, en forma formal, el primer ámbito sería escrito cuando ['&',
'&', ('cliente', '=', Cierto), ('usuario_id', '=', uid), ('lang',
'!=', 'fr_FR')].
Mientras un poco duro de leer para expresiones más grandes, la ventaja de operadoras de
prefijo es que su alcance es rigidly definido, el cual te salvas prpers teniendo que preocupar
aproximadamente operador precedence y paréntesis. Es siempre el siguiente dos
expresiones: El primero & aplica a ' &', ('cliente', '=', Cierto),
('usuario_id', '=', uid) como el primer operando y
('lang', '!=', 'fr_FR') como el segundo. Entonces, el segundo & aplica a ('cliente',
'=', Cierto) como el primer operando y ('usuario_id', '=', uid) como el segundo.
194
Capítulo 8
En la segunda acción, tenemos que escribir fuera de la forma llena porque necesitamos el |
operador.
hay también un ! Operador para negación, pero, equivalencias lógicas dadas y negated
operadores de comparación como != Y no en, no es realmente necesario. Nota que esto
es un unary operador de prefijo, así que sólo aplica a la expresión siguiente en el ámbito y
no a todo aquello sigue.
Nota que el operando correcto no necesita para ser un valor fijo cuándo escribes un ámbito
para una acción de ventana u otros ámbitos de lado del cliente. Puedes utilizar la misma
Pitón mínima cuando
Descrito más temprano para contextos, así que puedes escribir filtros como cambiados
última semana, mis socios, y tan encima.
Allí ha more...
Los ámbitos de preceder trabajan sólo en campos del modelo él, mientras a menudo
necesitamos filtrar basados en las propiedades de enlazó registros. Para hacer este, puedes
utilizar la notación también utilizada en
@api.Depende definiciones o relacionó campos: crear un salpicado path del modelo actual al
modelo quieres filtro para. Para buscar socios qué tener una persona de ventas que es un
miembro de un grupo que empieza con el G de letra, utilizarías el ámbito
[('user_id.groups_id.name', '=gusta', 'G%')]. El camino puede ser arbitrarily mucho
tiempo, así que sólo tienes que cuidar que hay campos de relación entre el modelo actual y el
modelo quieres filtro para.
Operadores
La mesa siguiente lista los operadores disponibles y su semantics:
Operador
(equivalente) Semantics
=, != (<>) Partido exacto, no igual (deprecated notación de no igual)
Controles si el valor es uno de los valores nombraron en una lista en el
En, no en correcto
Operando, dado como lista de Pitón: [('uid', 'en', [1, 2,
3])]
<, <= Más grande que, más grande o igual
>, >= Less que, menos o igual
Gusta, no gustar Controles si el operando correcto está contenido (subcadena) en el valor
ilike, no ilike Igual como el precediendo un pero el caso insensible
=Gusta, =ilike Puedes buscar patrones aquí: % partidos cualquier cuerda y _.
Mateches un carácter. Esto es el equivalente de PostgreSQL es gusta .
Niño_de Para modelos con un padre_id campo, esto busca niños del
Operando correcto, con el operando correcto incluido en los resultados.
Evalúa a cierto si el operando correcto esf alse, otherwise él behaves
=? gusta
"= -" Esto es útil cuándo generas ámbitos programmatically y
Quiere filtro para algún valor si está puesto, pero ignorarlo otherwise.
195
Backend Vistas
Pitfalls
Esto todo trabaja bien para campo tradicionals, pero un problema notorio está buscando el valor
de una función no almacenada campo. Es un problema que las personas a menudo omiten la
función de búsqueda, mientras esto es bastante sencillo para fijar por proporcionar la función
de búsqueda en vuestro código propio cuando descrito en
Capítulo 4, Modelos de Aplicación.
Otro asunto que podría desconcertar los desarrolladores es Odoo comportamiento cuándo
buscando a través de uno2muchos o muchos2muchos campos con un operador negativo.
Imagina tienes un socio con una etiqueta Un y buscas [('category_id.name', '!=',
'B')]. Vuestro socio aparece en el resultado y esto es qué esperaste. Pero si añades la
etiqueta B a este socio, él todavía
Aparece en vuestros resultados, porque para el algoritmo de búsqueda es bastante que hay uno
registro enlazado (Un en este caso) que hace not cumplir el criterio. Ahora si sacas la etiqueta Un
de modo que B es la etiqueta única, el socio será filtrado fuera. Si también sacas la etiqueta B de
modo que el socio no tiene ninguna etiqueta, es todavía filtrado fuera, porque condiciones en el
enlazó los registros presuponen tél existencia de este registro. En otras situaciones aun así, esto
es el comportamiento quieres, así que no es realmente una opción para cambiar el
comportamiento estándar. En caso necesitas un comportamiento diferente aquí, proporcionar
una función de búsqueda de vuestro propio aquello interpreta el negation la manera necesitas.
Ve también
Si nunca necesitas manipular un ámbito no creaste programmatically, uso la utilidad
funciona proporcionada en openerp.osv.Expresión. Especialmente es_hoja,
normaliza_ámbito, Y ,y O te dejará para combinar domains exactamente la
manera Odoo él. No esto tú, porque hay muchos casos de esquina tienes que
tener en cuenta y es muy probable pasarás por alto uno.
Para la aplicación estándar de ámbitos, ver las vistas de Búsqueda de la receta.
Vistas de lista
After Habiendo gastado bastante algún tiempo en la vista de forma, ahora tendremos una
mirada rápida en cómo para definir vistas de lista. Internamente, se apellidan vistas de
árbol en algunos sitios y vistas de lista en otros, pero, dados hay otra construcción dentro
del Odoo vista framework llamó árbol, nos aferraremos a el wording lista aquí.
196
Capítulo 8
Cómo trabaja...
Tú already saber la mayoría de qué pasa aquí. Definimos una vista, este tiempo de árbol de tipo,
y sujetarlo a nuestra acción con un ir.Acciones.Ventana_de acto.Elemento de vista. Así
que la cosa única dejó para hablar es el elemento de árbol y su semantics. Con una lista no
tienes muchos deelecciones de señal, así que los niños válidos únicos de este elemento son el
campo y elementos de botón.
Siguen el mismo semantics como más tempranos, salva para el hecho que hay mucho
menos elecciones para widgets – el sólo elecciones realmente interesantes son
progressbar, mcualquier2onebutton, y mango . El primer dos behave como sus
tocayos de forma. El mango es concreto de listar vistas. Está significado para campos
de entero y renders un arrastrar mango que el usuario puede utilizar para arrastrar una fila
a una posición diferente en la lista, así actualizando el valor del campo. Esto es útil para
secuencia o campos de prioridad.
Qué es nuevo aquí es el atributo de colores en el elemento de árbol. Contiene gobierna
qué color de fuente está escogido para la fila, dado en el color de forma: código de
Pitón, separado por puntos y comas. Elf irst el partido gana, tan lo que la vista anterior es a
render socios quiénes son ambos proveedor y cliente en azul, clientes en verdes, y
proveedores en rojos. En vuestro
Código de pitón, puedes utilizar los campos nombraste en la definición de vista, el cual es
por qué nosotros tiene que estirar el cliente y campos de proveedor también. Les
hicimos invisibles porque sólo necesitamos el dato y no quiere molestar nuestros usuarios
con aquellas dos columnas extras. Los colores posibles son los que HTML define, así que
puedes tampoco nombres de uso o un hex cuerda.
197
Backend Vistas
Allí ha más...
Para campos numéricos, puedes añadir una suma de atributo que causas esta columna
para ser summed arriba con el texto pusiste en el atributo como tooltip. Menos común es los
atributos avg, min, y max , aquella exhibición the media, mínimo, y máximo
respectivamente. Nota que estos cuatro trabajo único en los registros actualmente visibles,
así que podrías querer ajustar el límite de la acción (ve encima) en orden para el usuario
para ver todos los registros inmediatamente.
Análogo a los colores attribute en el elemento de árbol es el atributo de fuentes . Con
él, puedes escoger tener un récord ser intrépido, italic, o subrayar (sic). En la parte
correcta de una definición de fuente, puedes correr las mismas expresiones de Pitón tan
anteriormente. Hay una diferencia sutil though. Aquí, la última definición gana si las
expresiones múltiples aplican a una fila.
Un atributo muy interesante para el elemento de árbol es editable. Si pusiste esto a superior
o fondo , la lista behaves enteramente diferente que antes de que. Sin él, clicking una fila abre
una vista de forma
Para la fila. Con él, clicking una fila lo hace editable inline, con los campos visibles rendered
tan campos de forma. Esto es particularmente útil en embedded vistas de lista, los cuales
están hablados más tarde en este capítulo. La elección es si las líneas nuevas seránun dded
en el superiores o fondo de la lista.
Por default, los registros están ordenados según la _propiedad de orden del modelo
mostrado. El usuario puede cambiar ordenar por clicking un encabezamiento de columna,
pero puedes también puesto un orden inicial diferente por poner el default_propiedad
de orden en el elemento de árbol. La sintaxis es el mismo tan en _orden.
El crear, edita, y eliminar unttributes del trabajo de elemento del árbol igual en
cuanto al elemento de forma describió más temprano. También determinan los controles
disponibles si el atributo editable está puesto.
Vistas de búsqueda
Cuándo abriendo vuestra vista de lista, notarás el campo de búsqueda al aparejo
superiorht. Si escribes algo allí, consigues sugerencias sobre qué para buscar y hay
también un conjunto de predefined filtros para escoger de. Esta receta andará tú a
través de cómo para definir aquellas sugerencias y opciones.
198
Capítulo 8
Cómo a do lo...
1. Definir vuestra vista de búsqueda:
<Récord id="buscar_todo_modelo" de
clientes="ir.ui.Modelo"> <de nombre de campo="de
vista">res.Campo</de socio>
<Tipo de arco="de nombre" de
campo="xml"> <búsqueda>
<Campo de nombre="de
nombre" /> <de campo
categoría="de nombre_id"
Ámbito_de filtro="[('categoría_id', 'niño_de',
self)]" />
<Banco de nombre="del campo_ids"
widget="mucho2un" /> <filtro
proveedores="de nombre"
Ámbito="de Proveedores" de la
cuerda="[( esupplier', '=', Cierto)]"
/>
</Búsqueda>
</Campo>
</Récord>
Cuándo escribes algo ent busque barra ahora, serás ofrecido para buscar este plazo en el nombre,
categorías, y campos de cuentas del banco. Si vuestro plazo pasa para ser una subcadena de un
número de cuenta de banco en vuestro sistema, incluso serás ofrecido para buscar exactamente
para esta cuenta de banco.
Cómo trabaja...
En el caso de nombre , sencillamente listamos el campo cuando el para ser ofrecido al usuario
para buscar. Dejamos el semantics en el defaults, el cual es una subcadena busca campos de
carácter.
Para categorías, nosotros algo más interesting. Por default, vuestro plazo de búsqueda aplicó a
un muchos2mucha búsqueda de nombre de gatillos_de campo, el cual sería una búsqueda
de subcadena en el categorie nombres en este caso. Pero dependiendo de vuestra estructura de
categoría, pueda ser muy conveniente de buscar socios quiénes tienen la categoría estás
interesado en o un niño de él. Piensa aproximadamente
Una categoría principal Newsletter suscriptores con sub categorías Semanalmente
newsletter, Mensuales newsletter, y un par de otro newsletter tipos. Buscando newsletter
suscriptores con el preceding definición de vista de la búsqueda te dará todo el mundo
quién está suscrito a cualquiera de aquellos newsletters en uno va, el cual es mucho más
conveniente que buscando cada tipo solo y combinando los resultados.
199
Backend Vistas
El ámbito_de filtro attribute puede contener un ámbito arbitrario, así que eres tampoco
restringido a buscar el mismo campo nombraste en el atributo de nombre, ni a utilizar
sólo uno denomina. El variable self es lo que el usuario rellenó, y también la variable única
puedes utilizar aquí. Un más elaborate ejemplo del default vista de búsqueda para socias es:
<Filtro de nombre="de nombre" de campo_ámbito="['|','|', ('nombre_de
exhibición','ilike',self),( esf','=',self),('email','ilike',se
lf)]"/>
Esto deja el usuario a ni siquiera pensar mucho sobre qué para buscar; just tipo algunas
letras, golpe
Introduce, y, con un poco de suerte, uno de los campos mencionó contiene la cuerda
estamos buscando.
Para el banco_ids campo, utilizamos otro truco. El tipo de un campo no sólo decide el default
manera de buscar la entrada del usuario, también define la manera Odoo presenta las
sugerencias. Y dado muchos2un campos son el únicos unos aquella conclusión de coche de la
oferta, forzamos Odoo para hacer que, incluso aunque banco_ids es un un2mucho campo por
poner el widget atributo. Sin este, el offer sería sencillamente para buscar en este campo, sin
sugerencias de conclusión. El mismo aplica a muchos2muchos campos. Nota que cada campo
con un muchos2un widget el conjunto provocará una búsqueda en su modelo para cada uno del
usuario keystrokes – no utiliza demasiados de ellos.
También tendrías que poner el más utilizó campos hasta arriba, porque el primer campo es
qué está buscado si el usuario justo escribe algo y los golpes Introducen. También parece
valor mencionando que la barra de búsqueda es muy bien utilizable con el teclado;
seleccionar una sugerencia por pulsar el abajo flecha y abrir un muchos2unsugerencia de
conclusión por pulsar la flecha correcta. Si educas vuestros usuarios en este y parar
atención a un sensato ordenando de campos en la vista de búsqueda, serán mucho más
eficaces que por escribir algo primero, grabbing el ratón, y seleccionando alguna opción.
El elemento de filtro crea un botón que añade el contenido del atributo de ámbito del filtro
al ámbito de búsqueda. Tendrías que añadir un nombre internológico y
un atributo de cuerda a describe el filtro a vuestros usuarios.
Allí ha más...
Puedes agrupar los filtros con la etiqueta de grupo, el cual les causa para ser rendered
ligeramente más cercano junto que los otros filtros, pero esto tiene implicaciones semánticas
también. Si pusiste filtros múltiples en el mismo grupo y activar más de uno de ellos, sus ámbitos
serán combinados con el operador |, mientras filtros y campos no en el mismo grupo está
combinado con el operador &. Casos donde quieres la disyunción para vuestros filtros es cuándo
ellos filtra para mutually conjuntos exclusivos, en qué caso que selecciona tanto de ellos siempre
dirigirían a un conjunto de resultado vacío. Dentro del mismo grupo, puedes conseguir el mismo
efecto con el separator elemento.
Nota que si el usuario rellena consultas múltiples para el mismo campo, serán
combinados con | demasiado, así que no necesitas para preocuparse sobre aquel.
200
Capítulo 8
Así como el campo, el elemento de filtro puede tener un atributo de contexto cuyo contenido
será fusionado con el contexto actual y eventual otros atributos de contexto en la vista de
búsqueda. Esto es esencial para vistas que agrupación de soporte (ve recetas sobre kanban y
graph vistas), porque el contexto resultante determina el campo(s) para ser agrupado por con el
grupo clave_por. Miraremos a los detalles de agrupar en las recetas apropiadas, pero el
contexto tiene otros usos también. Por ejemplo, puedes esconder las columnas que dependen
de un valor de contexto por poner el atributo invisible del elemento de campo en la vista de
lista a algo como el siguiente:
Invisible="no contexto.Consigue( esqué_col1')"
Puedes utilizar un filtro para cambiar esta columna encima o fuera. O podrías escribir
un campo de función que regresos los valores diferentes que dependen de el contexto,
entonces puedes cambiar los valores por activar un filtro.
La búsqueda se ve también responde a context llaves. En una manera muy similar a default
valores cuándo creando registros, puedes pasar defaults para una vista de búsqueda vía el
contexto. Si habíamos puesto un contexto de { earch_default_proveedor': 1} en nuestra
acción anterior, el filtro de proveedores habría sido preselected en la vista de búsqueda. Esto
trabaja sólo si el filtro tiene un nombre aun así, el cual es por qué tú tener que siempre puesto lo.
Para poner defaults para campos en la vista de búsqueda, uso
Búsqueda_default_$fieldname.
Más allá, el campo y los elementos de filtro pueden tener unos grupos property con el mismo
semantics cuando en las vistas de forma para hacer el elemento sólo visible para grupos
seguros.
Ve también
Para detalles aproximadamente manipulando el contexto, ver la receta que Pasa
parámetros a formas y acciones: Contexto.
Después de actualizar vuestro módulo, tendrías que ver el campo extra Último actualizado
encima debajo el campo de sitio web en la forma de socio. Cuándo escribes en something
aquello parece una fecha (un dígito o dos) en la caja de búsqueda, tenga que proponer para
buscar socios último modificados en esta fecha, y en la vista de lista del socio, tendrías que
ver la fecha de modificación dejó de la columna de email.
202
Capítulo 8
Cómo trabaja...
El campo crucial aquí es, cuando probablemente has adivinado, hereda_id. Necesitas
pasarlo el XML ID de la vista quieres modificar (hereda de), y el campo de arco entonces
contiene instrucciones encima cómo para modificar el existiendo XML ingenio de nodoshin la
vista estás heredando de.
De hecho tendrías que pensar del proceso entero tan XML bastante sencillo
procesamiento, porque todas las partes semánticas vienen sólo mucho más tarde.
El más canonic instrucción dentro del campo de arco de una vista heredada es el elemento
de campo, el cual tiene el requerido atribuye nombre y posición . Porque puedes tener cada
campo sólo una vez en una forma, el nombre ya singularmente identifica un campo, y con el
atributo de posición, podemos colocar cualquier cosa pusimos dentro del elemento de
campo tampoco antes de que (1), interior (2), o después de que (3) el campo
nombramos. El default es interior, pero para readability siempre tendrías que nombrar la
posición significas. Recuerda que no estamos hablando semantics aquí; esto es sobre la
posición en el pariente de árbol del XML al field hemos nombrado. Cómo esto será rendered
después es un asunto completamente diferente.
Ejemplo 2 encima demuestra una aproximación diferente. El xpath el elemento selecciona
el primer elemento que empareja el XPath la expresión nombrada en el atributo expr.
También, aquí el atributo de posición dice el procesador dónde para poner el xpath
los contenidos del elemento.
XPath Podría mirar un poco scary, pero es un medio muy eficaz de seleccionar el nodo
necesitas trabajar encima. Tomar el tiempo para mirar a través de algunas expresiones
sencillas, eswor th lo. Probablemente en el tutorials encontrarás, tú tropezón al nodo de
contexto del plazo a qué algunas expresiones es relativo. En Odoo herencia de vista, aquello
es siempre el elemento de raíz de la vista estás heredando de.
Para todo los otros elementos encontrados en el campo de arco de una vista de
heredar, el procesador busca el primer elemento con el mismo nombre de nodo y
emparejando atributos (con la posición de atributo excluyó, cuando esto es parte de la
instrucción). Uso esto sólo en casos donde es muy improbable que esta combinación no
es única, como un elemento de grupo combinado con un atributo de nombre.
Allí ha más...
El atributo de posición tiene dos otros valores posibles: reemplaza y atributos . Utilizando
reemplaza causa el elemento seleccionado para ser reemplazado con el contenido del
elemento de instrucción. Consiguientemente, si no tienes cualquier content, el elemento
seleccionado es sencillamente sacó.
En la lista o vista de forma encima causarían el campo de email para ser sacado.
203
Backend Vistas
Utilizando los atributos tiene un muy diferentes semantics de todo del encima. El
procesador eln espera el elemento para contener los elementos de atributo con un
atributo de nombre. Aquellos elementos entonces soler atributos de conjunto en el
elemento seleccionado. Si quieres heed el aviso de arriba, tú mejor puesto el atributo
invisible a 1 para el email campo:
<Posición de email="de nombre" de
campo="nombre"> <de atributo de los
atributos="invisible">1</atributo>
</Campo>
Ve también
Para heredar vistas, un muy útiles y no muy bien el campo sabido es grupos _id. Esta causa de
campos la herencia para tener lugar sólo si el usuario que pide la vista de padre es miembro de
uno de los grupos mencionó allí. Esto te puede salvar mucho trabajo cuándo adaptando la
interfaz de usuario para niveles diferentes de acceso, porque con herencia puedes have
operaciones más complejas que justo mostrando o no mostrando los elementos basaron encima
afiliación de grupo, cuando es posible con los grupos atribuyen encima elementos de forma
como discutidos más tempranos. Por ejemplo puedes sacar elementos si el usuario es miembro
de algún grupo (which es el inverse de qué el atributo de grupos ), pero también algunos
bastante elaborar a trucos les gustan añadir los atributos basó encima afiliación de grupo,
piensa sobre a cosas sencillas les gusta hacer un campo leído sólo para grupos seguros, o más
interesantes a unos les gusta utilizar different widgets para grupos diferentes.
Qué estuvo descrito aquí es el caso si el campo de modo de la vista original está puesto a
primario, mientras las vistas de heredar tienen extensión de modo, el cual es el default.
Miraremos al caso que modo de un heredando view está puesto a primario más tarde, donde
las reglas son ligeramente diferentes.
Documento-formas de estilo
En esta receta, revisaremos algunas directrices de diseño para presentes una experiencia de
usuario uniforme.
205
Backend Vistas
4. Pone botones que enlace a los recursos pertinentes para el objeto en su caja propia (if
aplicable):
<div Clase="oe_correcto oe_botones_de nombre" de
caja="de botón"> <nombre de
botón="abre_algo_interesante"
La cuerda="Abre algunos enlazaron clase"
de objeto="de tipo"
récord="oe_stat_botón" />
5. Añadir vuestro contenido, posiblemente dentro de una libreta si hay mucho fields:
<Nombre de
grupo="algún_campo"> <de
nombre de campo="de
campos1" /> <nombre de
campo="campo2" />
</Grupo>
Cómo trabaja...
El encabezamiento tendría que contener botones que ejecuta acciones en el objeto el
usuario actualmente ve. Uso el oe_clase de punto destacado para hacer los botones
visually destacar (aquello es brillante azul en el time de escribir), el cual es una manera
buena de guiar el usuario que considera cuál sería la acción más lógica para ejecutar en el
momento. Prueba tener todo el destacó botones a la izquierda del no-destacó botones y
esconder los botones no pertinentes en el current estado (si aplicable). Si el modelo tiene un
estado, espectáculo él en el encabezamiento que utiliza el statusbar widget. Esto será
rendered bien alineado en el encabezamiento.
El elemento de hoja es rendered como la hoja estilizada y la mayoría de campos importantes
tendrían que ser el primer thing el usuario ve cuándo mirando en él. Uso el oe_título y
oe_dejó clases para tenerles rendered en un sitio prominente (flotando dejado con fuente
ajustada ligeramente medidas en el tiempo de escribir).
Si hay otros registros de interés respecto del récord el usuario actualmente ve (como las
facturas del socio en una forma de socio), puesto les en un elemento con el oe_correcto y
oe_Clases_de caja del botón; esto alinea los botones en él a la derecha. En los botones
ellos, uso el oe_stat_clase de botón para aplicar un uniforme rendering de los botones.
Incluso en caso tú no así diseño, aferrarse a el elemento y nombres de clase
describieron aquí, y ajustar qué necesitas con CSS y posiblemente
Javascript. Esto hará la interfaz de usuario más compatible con el existiendo
addons y dejarte para integrar mejor con el núcleo addons.
206
Capítulo 8
Esto hará el padre de campo_id invisible si el socio es una compañía , unnd requirió si
no es una compañía.
Cómo trabaja...
El attrs el atributo contiene un diccionario con las llaves invisibles, requeridos, y
readonly (todo de ellos opcionales). Los valores son ámbitos que puede referir a los
campos que existen en la forma (y realmente only aquellos, así que ningún camino
salpicado), y el diccionario entero está evaluado según las reglas para Pitón de lado del
cliente describieron más tempranas. Tan por ejemplo, puedes acceder el contexto en el
operando de mano correcto.
Allí ha más...
Mientras este mecanismo es bastante straightforward para los campos escalares, es
menos obvio cómo para manejar el2muchos y muchos2muchos campos. De hecho, en
estándar Odoo puedes no mucho con aquellos campos dentro de un attrs atributo.
Pero si sólo necesitas comprobar si tal campo es vacío o no, nose [[6, Falso, []]]
como vuestro operando de mano correcto.
Embedded Vistas
Cuándo muestras un un2muchos o un muchos2mucho campo en una forma, no tienes mucho
control encima cómo es rendered hasta ahora si no has utilizado uno del especializado widgets.
También, en el caso de muchos2un campos, es deseable a veces para ser capaz de influir la
manera el registro enlazado está abierto. En esta receta, miraremos a cómo para definir vistas
privadas para aquellos campos.
207
Backend Vistas
3. Cercano la etiqueta:
</Campo>
Cómo trabaja...
Cuándo Odoo carga una forma, él primero controles para campos de referencia si hay
vistas embedded tan perfilados anteriormente. Aquellos embedded las vistas pueden
tener los elementos mismos exactos como vistas definimos before. Sólo si Odoo no
encuentra un embedded vista de algún tipo, utilice el modelo default vista de este tipo.
Allí ha más...
Mientras embedded las vistas parecen como una característica grande en primer lugar,
complican herencia de vista mucho. Por ejemplo, cuandotan encima tan embedded las
vistas están implicadas, los nombres de campo no son guaranteed para ser únicos y
normalmente tendrás que utilizar algunos bastante elaborar XPaths para seleccionar
elementos dentro de un embedded vista.
Tan, en general, tienes que mejor sirvió definir el standalone vistas y utilizar la vista
de forma_de las llaves_ref y vista_de árbol_ref describió más temprano.
208
Capítulo 8
Kanban Vistas
Hasta ahora, hemos presentado el usuario con una lista de registros que puede ser abierto
para mostrar una forma. Mientras aquellas listas son eficaces cuándo presenting mucha
información, tienden para ser bastante atenuar dado la carencia de posibilidades de
diseño. En esta receta, tendremos una mirada en kanban vistas, los cuales nos dejamos
a listas presentes de registros en un más apelando manera.
3. Algún diseño:
<Plantillas>
<t t-Nombre="kanban-cajas">
<div
Clase="oe_kanban_tarjeta"
> <un tipo="abierto">
<Nombre de nombre="del campo" />
</Un>
<t t-
Si="récord.Proveedor.Valor_crudo
o récord.Cliente.Valor_crudo">
Es
<t t-
Si="récord.Cliente.Valor_crudo">
un cliente
<t t-
Si="récord.Proveedor.
Valor_crudo"> y /t.
<>
</t>
<t t-
Si="récord.Proveedor.Valor_crudo
"> un proveedor
</t>
</t>
</div>
</t>
</Plantillas>
209
Backend Vistas
5. Añadir esta vista a uno de vuestras acciones. Esto queda como un ejercicio para el
lector.
Cómo trabaja...
Necesitamos dar una lista de campos para cargar en (2) para ser capaces de accederles
más tarde. El contenido del elemento de plantillas tiene que ser un solo t elemento con
el attribute t-nombrar puesto al valor kanban-cajas.
Qué escribes dentro de este elemento será repetido para cada registro, con especial
semantics para el t elementos y el t-* atributos. Para detalles aproximadamente que,
refiere a Capítulo 15, Desarrollo de Cliente de la Web, y el recipe lado de Cliente QWeb
porque, técnicamente, kanban las vistas son una repetición de QWeb plantillas.
Hay unas cuantas modificaciones qué es extraño a kanban vistas. Tienes acceso al caso
de variables, modo_único_leído, registro, y widget . Los campos pueden ser
accessed por utilizar registro.fieldname, El cual es un objeto con el valor de
propiedades y valor_crudo , donde el valor es el campo valor formatted en una
manera presentable al usuario y el valor_crudo es el valor del campo cuando proviene
la base de datos.
Nota el atributo de tipo del enlace en la parte superior de la plantilla. Estas marcas de
atributo Odoo generar un enlace que obolígrafos el registro en el modo de vista (abierto) o en el
editar modo (edita), o elimina el registro (elimina). El atributo de tipo también puede ser
objeto o acción , el cual render enlaces que llamada una función del modelo o una acción. En
ambos casos, necesitas a supplement los atributos para los botones en forma ve tan
perfilados más tempranos. En vez del un elemento, también puedes utilizar el elemento de
botón; el atributo de tipo ha igual semantics allí.
Allí ha más...
hay unos cuantos más helper valor de funciones que menciona. Yof necesitas generar un
pseudo-color aleatorio para algún elemento, uso la función
kanban_color(algunos_variables), el cual regresará un CSS clase que conjuntos el
de fondo y propiedades de color. Esto es normalmente utilizado en el t-att-
elementos de clase.
210
Chapter 8
Preparándose
Ahora y en el resto de este capítulo, haremos uso del módulo de proyecto aquí cuando define
modelos que los deja mejores de datar y el estado basó vistas que los definidos en el módulo de
base. Tan antes procediendo, añade proyecto a la lista de dependencias de vuestro addon.
2. Añadir una carta y una acción que utiliza esta vista. Esto queda como un ejercicio para el
lector.
211
Backend Vistas
Cómo trabaja...
Kanban views Agrupación de soporte, el cual te dejas para mostrar registros que tiene el
campo de grupo en común en la misma columna. Esto es generalmente utilizado para un
estatal o etapa_id campo, porque deja el usuario para cambiar el valor de este campo
para un registro por sencillamente arrastrando él a otra columna. Pone el atributo
default_grupo_por en el kanban elemento al nombre del campo quieres grupo por
para uso de marca de esta funcionalidad.
Allí ha más...
Si no definido en el atributo dedicado, cualquier filtro de búsqueda puede undd agrupación
por poner una llave de contexto grupo nombrado_por al nombre de campo(s) para agrupar
por.
Vistas de calendario
Estos paseos de receta tú a través de cómo para mostrar y editar información sobre fechas
y duraciones en vuestros registros en una manera visual.
2. Añade las cartas y las acciones que utilizan esta vista. Esto queda como un ejercicio para
el lector.
Cómo trabaja...
Las necesidades de vista del calendario para ser nombres de campo pasado en el inicio de
fecha_de los atributos y parón_de fecha para indicar which campos para mirar en
cuándo construyendo la representación visual. Campos de uso de escribir Datetime
cuando todo más te conseguirá resultados extraños. Mientras inicio_de fecha está
requerido, puedes dejar fuera parón_de fecha y poner el retraso de fecha_del
atributo en cambio, el cual está esperado para ser un campo de Flotador que
representa la duración en horas.
212
Capítulo 8
La vista de calendario te dejas para dar graba cuáles tienen el mismo valor en un campo igual
(Arbitrariamente asignado) color. Para utilizar esta funcionalidad, puesto el color de
atributo al nombre del campo necesitas. En nuestro ejemplo, podemos ver en uno mira
qué tareas pertenecen al mismo proyecto, porque asignamos proyecto_id como el
campo para determinar los grupos de color.
Los campos nombras en el cuerpo del elemento de calendario está mostrado ingeniohin el
bloque que representa el intervalo de tiempo cubrió, separado por comas.
Allí ha más...
La vista de calendario tiene algunos otros atributos útiles. Si quieres entradas de calendario
abierto en un popup en vez de la vista de forma estándar, acontecimiento de
conjunto_abierto_popup a 1 . Si quieres ser capaz de crear una entrada nueva por
justo rellenando algún texto, puesto rápidamente_añadir a 1 . Internamente, esto llama
el nombre del modelo_crea función a de hecho crear el registro.
Si vuestro modelo tiene una idea de cubrir un día entero, puesto todo_día a un field
nombre que es cierto si las cubiertas récord el día entero, y falso otherwise.
En caso necesitas más bien grained control sobre el texto mostrado dentro de los
elementos de calendario, puestos la exhibición de atributo a una cuerda de formato
que utiliza nombres de campo en paréntesis. En our caso, podríamos decir
exhibición="[nombre] (asignado a [usuario_id])" para tener una
representación más verbosa del cual la tarea está asignada a quien.
Nota que esta receta información contenida sobre un tipo de vista del legado gantt, el
cual ha sido obsoleted durante escribir y estuvo sacado del texto.
Preparándose
Todavía estamos haciendo uso del módulo de proyecto aquí. Primero, necesitamos alguna
configuración. Activar el checkbox Dirige valoración de tiempo en tareas en Encuadres | de
Configuración y también instalar el proyecto de módulo_timesheet para ser capaz de grabar algún
tiempo en tareas diferentes.
Ahora crear algunos proyecta significados para ser proyectos de paraguas para los clientes.
Entonces, crear un par de tareas para cada proyecto de cliente. Están significados a
modelo actividades diferentes tienes por cliente. Asigna directores diferentes a estos
proyectos y activar las tareas de Uso de la caja. Finalmente, crear tareas ent hese
proyectos, dar una valoración de tiempo por tarea, y escribir algunas horas de trabajo en
estas tareas.
213
Backend Vistas
3. Añade las cartas y las acciones que utilizan esta vista. Esto queda como un ejercicio para
el lector.
Si todo fue bien, tendrías que ver graphs aquello te muestras quéhombre y las horas estuvieron
trabajadas por cliente (los proyectos definimos) bajo la responsabilidad de los directores de
proyecto diferentes.
Cómo trabaja...
El atributo de tipo determina el modo inicial de un graph vista. Los valores posibles son
pivote , barra, línea, y gráfico , mientras la barra es el default. El graph la vista es altamente
interactiva, así que el usuario puede cambiar entre los modos diferentes y también añadir y
sacar campos.
214
Capítulo 8
Los elementos de campo dicen Odoo qué para mostrar en qué eje. Para todo el graphmodo s,
necesitas al menos un campo con fila de tipo y uno con medida de tipo para ver cualquier cosa
útil. Los campos de fila de tipo determinan la agrupación, mientras posiciones de medida del tipo
para el valor(s) para ser mostrado.
Línea graphs soporte único un campo de cada tipo, mientras gráficos y mango de barras dos
campos de grupo con uno miden amablemente. La mesa de pivote apoya una cantidad
arbitraria de grupo y campos de medida. Ninguna preocupación, las cosas no rompen si
cambias a un modo que no apoya la cantidad de grupos y medidas definiste. Es justo que
ignorarán algunos de los campos y no siempre mostrar un resultado muy interesante.
Allí ha más...
Para todo el graph tipos, el Datetime los campos son delicados para agrupar, porque
raramente encontrarás el mismo valor de campo aquí. Tan si tienes un Datetime campo
de fila de tipo, también especificar el atributo de intervalo con uno de los valores
siguientes: día, semana, mes, trimestre, o año . Esto causará la agrupación para tener lugar
en el intervalo dado.
La mesa de pivote también apoya agrupar en columns. Tipo de uso col para los campos
quieres haber allí.
QWeb Informes
La última parte de la capa de presentación está imprimiendo fuera de informes. En
caso has no cultivar ahora, instala wkhtmltopdf tan descrito en Capítulo 1,
Instalando el Odoo Entorno de Desarrollo otherwise no conseguirás reluciente PDFs
cuando resultado de vuestros esfuerzos.
Preparándose
El mecanismo de conversión a PDFs está implementado en el addon informe, así que lo
tendrías que añadir tan dependencia de vuestro addon. También control doble que el
parámetro de configuración
Web.Base.url (O alternativamente, informe.url) Es un URL accesible de vuestro Odoo
caso, otherwise generación de informe toma las edades y el resultado mira divertidosny.
215
Backend Vistas
Ahora cuándo abriendo una forma de socio o seleccionando socios en la vista de lista,
tendrías que seroffe rojo para imprimir la lista de cumpleaños.
Cómo trabaja...
En vez de utilizar la sintaxis récord cuando nosotros más tempranos, utilizamos el elemento
de plantilla aquí. Esto es enteramente para comodidad; QWeb las vistas son vistas justas
cuando todo el otros. La razón para utilizar este elemento es que el campo de arco de QWeb las
vistas tiene que seguir reglas bastante estrictas y el elemento de plantilla cuida para generar
un arco contenta cuál cumple estas reglas.
No se preocupa sobre la sintaxis dentro del elemento de plantilla ahora. Este tema será
dirigido extensoly en la receta QWeb en Capítulo 14, Desarrollo de Sitio web del CMS.
216
Capítulo 8
Allí ha más...
Hay algunas clases de marcador en HTML de un informe aquello es crucial para el diseño. Ser
seguro para envolver todo vuestro contenido en un elemento con el conjunto de página de
la clase. Si olvidas que, verás nada en absoluto. To Añade un encabezamiento o footer a
vuestro registro, uso el encabezamiento de clase o footer .
También recordar que esto es HTML , así que uso de marca de CSS atributos como
página-rotura-antes de que, página-rotura-después de que, y página-
rotura-interior .
Habrás notado que todo de nuestro cuerpo de plantilla está envuelto en dos elementos con el
t-conjunto de atributo de la llamada. Examinaremos la mecánica de este atributo más tarde,
pero es crucial que te
Hacer igual en vuestros informes. Estos elementos cuidan que el HTML generó enlaces a todo
el necesarios CSS archiva und contiene algunos otro dato necesitado para la generación de
informe.
Mientras html_el contenedor no realmente tiene una alternativa, el segundo t-la
llamada también podría ser informe.Diseño_externo. La diferencia es que el diseño
externo ya viene con un encabezamiento y footer mostrando el logotipo de compañía, el
nombre de la compañía, y algunos otra información esperas de la comunicación externa de
una compañía, mientras el diseño interno justo te das un encabezamiento con paginación, la
fecha de impresión, y el nombre de la compañía. Por el bien de consistency, siempre utilizar
uno del dos.
En ordena no para tener que repetir mucho código, haremos uso de los modelos defined en
Capítulo 4,
Modelos de aplicación. Tan para seguir los ejemplos, grab el código de este capítulo.
Introducción
En este capítulo, miraremos en cómo addons puede proporcionar dato en tiempo de
instalación. Esto es útil para proporcionar default valores y añadiéndometadata como
descripciones de vista, cartas, o acciones. Otro uso importante está proporcionando dato de
manifestación, el cual está cargado cuándo la base de datos está creado con el dato de
manifestación de la Carga checkbox activó.
219
Dato de módulo
Cómo trabaja...
Un XML ID es una cuerda que refiere a un registro en la base de datos. El IDs ellos es
registros de modelo ir.Modelo.Dato. Las filas de esta mesa contienen el que declaran
módulo ID, la cuerda de identificador, el modelo referido, y el referido ID. Cada vez un ID
tiene que ser mirado arriba, Odoo controles si la cuerda es namespaced ya (aquello es,
contiene exactamente un punto), y si no añade el nombre de módulo actual como
namespace. Entonces mira arriba si hay ya un registro en ir.Modelo.Dato con el nombre
especificado. Si tan, una declaración de ACTUALIZACIÓN para el listó los campos está
ejecutado; si no, un CREAR la declaración está ejecutada. Este is por qué puedes dar dato
parcial cuándo un récord ya existe, cuando nosotros encima.
Una aplicación extendida para dato parcial, aparte de cambiar los registros
definieron por otros módulos, está utilizando un elemento de atajo para
crear un registro en una manera conveniente y escribiendo un campo en
este récord cuál no es apoyado por el elemento de atajo:
<Ventana_de acto id="mi_acción" nombra="Mi
modelo" de acción="res.Socio"
/>
<Récord id="mi_modelo" de
acción="ir.Acciones.Nombre_de campo"> <de ventana
de acto="búsqueda_de coche" eval="Falso" />
</Récord>
220
Capítulo 9
El ref función, cuando utilizó abajo en la receta que Carga el dato que utiliza XML
archivos, también añade el módulo actual como namespace si apropiado, pero levanta un
error si el XML resultante ID no existe ya. Esto también aplica al id atributo si it no es
namespaced ya.
Allí ha más...
Probablemente necesitas acceder registros con un XML ID de vuestro código tarde o
temprano. Uso la función self.env.ref() En aquellos casos, el cual regresa un explorar
récord del referenced registro. Nota que aquí, te unlways tiene que pasar el XML lleno ID.
Ve también
Consultar la receta que Utiliza el noupdate y forcecreate banderas para descubrir por qué
el nombre de la compañía está cambiado sólo encima instalación del módulo.
221
Dato de módulo
<Liberación de fecha="de nombre_de campo">2016-03-
01</campo>
<Autor de nombre="del campo_ids" eval="[(6, 0,
[ref('autor_af'), ref('autor_dr'),
ref('autor_hb')])]" />
<Editor de nombre="del campo_id"
ref="res_socio_packt" /> </registro>
</odoo>
Cuándo actualizas vuestro módulo ahora, verás de todas formas el editor creamos, y, si
vuestra base de datos ha demo el dato habilitó, cuando señalado out en Capítulo 1,
Instalando el el Odoo Entorno de Desarrollo, también encontrarás este libro y sus autores.
Cómo trabaja...
Cuando has visto encima, demo el dato es técnicamente justo igual dato tan normal. La
diferencia única es que el primero está estirado por el demo llave en el manifestar, el último por
la llave de dato.
Para crear un registro, uso el elemento récord, el cual tiene los atributos obligatorios id
y modelo . Para el id atributo, consultar la receta que Utiliza externo IDs y
namespaces; el atributo de modelo refiere to la propiedad de nombre de _un modelo.
Entonces utilizas el elemento de campo para llenar columnas en la base de datos cuando
definido por el modelo nombraste. El modelo también decide cuáles son los campos
obligatorios para llenar y también posiblemente define default valores, en qué caso tú no
need para dar aquellos campos un valor explícitamente.
Cuando mostrado encima, el elemento de campo puede contener su valor como texto sencillo en
caso de valores escalares.
Para instalar referencias, hay dos posibilidades. El más sencillo está utilizando el ref atributo, el
cual trabaja para muchos2un campos y justo contiene el XML ID del récord de ser referenced.
222
Capítulo 9
Allí ha más...
Mientras puedes hacer básicamente cualquier cosa con el elemento récord, hay elementos
de atajo definió aquello lo hace más conveniente parath e desarrollador para crear clases
seguras de registros.
Los ejemplos son menuitem, plantilla o ventana de acto. Refiere a Capítulo 8, Backend
Vistas y
Capítulo 14, Desarrollo de Sitio web del CMS para información sobre aquellos.
Un elemento de campo también puede contener el elemento de función, el cual llama una
función definida en un modelo para proporcionar el valor de un campo. Ver la receta que Utiliza
el noupdate y forcecreate banderas para una aplicación donde sencillamente llamamos una
función a directamente escribir a la base de datos, circumventing el mecanismo de cargar.
223
Dato de módulo
El encima la lista pierde fuera de entradas para 0 y 1 , porque no son muy útiles cuándo
cargando dato. Están introducidos como sigue por el bien de completeness:
f(0, Falso, {'llave': valor})crea un registro nuevo del referenced
modelo,with sus campos llenaron del diccionario en posición tres. El segundo
elemento del tuple está ignorado. Cuando aquellos registros no tienen un XML ID y está
evaluado cada vez el módulo está actualizado, dirigiendo para plegar entradas, es
mejor en general para evitar this, crear el registro en su elemento récord propio, y
enlazarlo cuando será explicado más tarde.
f(1, id, {'llave': valor})puede soler escribir en un existiendo registro
enlazado.Para las mismas razones tan encima, tendrías que evitar esta
sintaxis.
Utilizarás ambos de ellos extensively en Capítulo 5, Lado de Servidor Básico Lógica
Empresarial.
224
Capítulo 9
Cómo trabaja...
El odoo el elemento puede tener un noupdate atributo, el cual está propagado al
ir.Modelo.El dato graba creado cuándo leyendo los registros de dato cerrados por primera
vez, acabando como columna en esta mesa.
When Odoo Instala un addon (llamado init modo), todo noupdate los registros están
escritos. Cuándo actualizas un addon (modo de actualización llamada), existiendo XML
IDs está comprobado para ver si tienen el noupdate conjunto de bandera, y si tan,
elementos intentando escribir a este XML ID es ignored. Esto no es el caso si el récord en
cuestión estuvo eliminado por el usuario, el cual es por qué tú puede forzar no recreando
noupdate registros también en modo de actualización por poner la bandera forcecreate en
el récord a falso .
Allí ha more...
Puedes forzar init modo por empezar vuestro Odoo servidor con el parámetro --
init=vuestro_addon, de este modo overwriting todo existiendo noupdate registros. Esto
también la causa eliminó registros de ser recreados. Nota que esto puede causar registros dobles
y errores de instalación relacionada si un módulo circumvents el XML ID mecanismo, por ejemplo,
por crear registros en código de Pitón llamado por
YAML Archivos.
Para módulos escribes de arañazo, no necesitas para preocuparse demasiado sobre noupdate
registros en cualquier vuestro propios addon or otro unos, mientras sólo lo instalas después de
todo desarrollo
Está hecho. Pero imaginar añades una característica nueva a un módulo de existir que es
ya fuera en el salvaje. Entonces podrías necesitar poner un valor concreto encima, por
ejemplo, el socio principal, el cual es un noupdate registro. Para usuarios con una versión
anterior ya instalada, esta actualización de dato nunca será ejecutada! Puedes trabajar
alrededor esto por utilizar el elemento de función a temporalmente unset el récord a
noupdate, como sigue:
<Nombre de función="escribe"
modelo="ir.Modelo.Búsqueda"> <de nombre de
función="de dato" modelo="ir.Modelo.Dato">
<Valor eval="[( soyodule', '=', 'base'), ('nombre', '=',
soyain_ socio')]" />
</Función>
<Valor eval="{'noupdate': función}"
/> </Falsa>
<Récord id="base.Modelo_de socio" principal="res.Socio">
<field Libro="de nombre_ids" eval="[(4,
ref('recetario_de libro'))]" </registro>
225
Dato de módulo
<Nombre de función="escribe"
modelo="ir.Modelo.Búsqueda"> <de nombre de
función="de dato" modelo="ir.Modelo.Dato">
<Valor eval="[( soyodule', '=', 'base'), ('nombre', '=',
soyain_ socio')]" />
</Función>
<Valor eval="{'noupdate': función}"
/> </Cierta>
Con este código, puedes circumvent cualquier noupdate bandera, pero ser seguro esto es
realmente qué quieres.
Otra opción para solucionar el escenario sketched aquí es para escribir un guión de
migración, tan fueratachado en la receta siguiente.
Ve también
Odoo También utiliza XML IDs para mantener pista del cual los datos es para ser eliminados
después de un addon actualización. Si un registro tuvo un XML ID del módulo namespace
antes de la actualización, pero el XML ID no es restablecido durante el update, el récord y su
XML ID será eliminado de la base de datos porque están considerados obsoletos. Para una
discusión más profunda de este mecanismo, ver la receta siguiente: Addon actualizaciones
y migración de dato.
226
Capítulo 9
Ahora tenemos un ACL que permisos usuarios normales para leer registros de libro, pero no
les deja para editar, crea o delete les.
Cómo trabaja...
Sencillamente caes todos vuestros archivos de dato en vuestro manifestar es lista de dato.
Odoo Utilizará la extensión de archivo para decidir qué tipo de archiva es. Una especialidad
de CSV los archivos es que su nombre de archivo tiene que emparejar el nombre del modelo
para ser imported, en nuestro caso, ir.Modelo.Acceso. Las primeras necesidades de línea
para ser un encabezamiento con columna nombra que partido los nombres de campo del
modelo exactamente.
Para valores escalares, puedes utilizar un citado (si es necesario porque la cuerda
contiene cita o comas él) o un unquoted cuerda.
Cuándo escribiendo muchos2un campos con un CSV archivo, Odoo primero intenta
interpretar el valor de columna como un XML ID: Si no hay ningún punto, añadir el nombre
de módulo actual como namespace, lookup el resultado enir.Modelo.Dato. En caso esto
falla, el nombre del modelo_search la función se apellida con el valor de la columna como
el parámetro y el primer resultado regresaron gana. Cuándo este también falla, la línea está
considerada nula y Odoo levanta un error.
Allí ha más...
Importador un2muchos y muchos2muchos campos con CSV los archivos es posibles, pero un
poco delicados. En general, estás apostadoter fuera creando los registros por separado e
instalando la relación con un
Archivo de XML después, o trabajando con un segundo CSV archivo que instala la relación.
Si te realmente necesidad de crear relacionada graba dentro del mismo archivo, orden vuestras
columnas tantha t todos los campos escalares son a la izquierda y los campos del modelo
enlazado son a la derecha, con un encabezamiento de columna que consta de el nombre del
campo de enlazar y el campo del modelo enlazado, separado por un colon:
"id","nombre","modelo_id:id","perm_leído","perm_leído",
"grupo_id:nombre", "usuario_de libro_de biblioteca_de acceso","ACL
para libros","libro_de biblioteca_del modelo",1,"mi grupo"
Esto crearía un grupo llamó mi grupo, podrías escribir más campos en el registro de grupo
por añadir columnas a la derecha. Si necesitas enlazar registros múltiples, repetir la línea y
sólo cambiar las columnas de mano correctas como apropiados. Dado que Odoo llena
columnas vacías con el valor de la línea anterior, no necesitas para copiar todos los datos,
pero sencillamente añadir una línea con valores vacíos salvó para los campos del modelo
enlazado quierest o llena.
227
Dato de módulo
Nosotros el mismo tan en la primera receta, pero en YAML sintaxis. Nota que YAML los
archivos necesitan la extensión .yml Para ser reconocido correctamente.
Cómo trabaja...
Odoo Introduce un YAML datatype registro, el cual es donde la mayoría del Odoo-
el comportamiento concreto está implementado. Cuando con XML, unas
necesidades récord un ID y un modelo puesto para algo útil.
Para valores de campo, utilizas YAML notación estándar, el cual significa no necesitas citando para
cuerdas. Cuándo llenando muchos2un campos, Odoo sencillamente presupondrá aquello qué das
aquí es un
XML ID, tan no hay ninguna necesidad para extra marcando aquí tampoco.
Allí ha más...
Hemos visto que enlazando un2muchos y muchos2muchos campos es un poco incómodos
con XML y CSV, y en el ejemplo encima, utilizamos la misma sintaxis para hacer el enlazando.
En YAML, lo podrías haber hecho más elegantemente por sencillamente escribiendo el
siguiente:
-
!Récord {id: recetario_de libro, modelo:
biblioteca.Nombre} de libro: Odoo recetario
Nombre_corto: liberación
de fecha_del recetario:
2016-03-01 autor_ids:
- Nombre: Alexandre Fayolle
- Nombre: Daniel Reis
- Nombre: Holger Brunn
De este modo, creaste tres registros de tipo res.Socio, enlazado en el autor de campo_ids.
Nota que aquí también, creando registros inline significa tienen ningún XML ID, el cual lo
hace difícil de referir a ellos de otros sitios.
Ve también
Esta receta focused encima utilizando YAML archivos para cargar dato. Si estás interesado
en probar utilizando YAML archivos, refiere a Capítulo 7, Depurando y Testaje Automatizado.
Sin este código, Odoo habría rebautizado la columna de liberación_de fecha vieja para
datar_la liberación_ movida y creó un nuevo un, porque hay no conversión automática de
campos de carácter para datar campos. Del punto de vista del usuario, el dato en
liberación_de fecha sencillamente sería ida.
230
Capítulo 9
Cómo trabaja...
El primer punto capital es que aumentas el version número de vuestro addon, cuando las
migraciones corridas sólo entre versiones diferentes. Durante cada actualización, Odoo escribe
el número de versión del manifestar en el tiempo de la actualización a la mesa ir_módulo_de
módulo. El número de versión está prefijado con Odoo versión importante y menor, si el
número de versión tiene tres
O menos componentes. En el ejemplo encima, nosotros explícitamente también nombrados
Odoo versión importante y menor, el cual es práctica buena , pero un valor de 1.0.1 habría
tenido el mismo efecto, porque, internamente, Odoo prefixes números de versión corta para
addons con su versión importante y menor propia número. Generalmente, utilizando la
notación larga es una cosa buena porque puedes ver con justo una mirada en el manifestar
archivo para qué versión de Odoo un addon está significado.
El dos migration los archivos son código justo archiva aquello no necesita para ser
registrado anywhere. Cuándo actualizando un addon, Odoo compara el addon versión
cuando notado en ir_módulo_de módulo con la versión en el addon es manifiesta. Si
el manifestar es la versión es más alta (después de que posiblemente undding Odoo
versión importante y menor), este addon carpeta de migraciones será buscada si
contiene carpetas con la versión(s) en entre, hasta, e incluyendo la versión que es
actualmente actualizó.
Entonces, dentro de las carpetas encontradas, busca Python archivos cuyo inicio de
nombres con pre- , les carga, y les espera para definir una función llamó emigrar, el cual
tiene dos parámetros. Esta función se apellida con un cursor de base de datos como el
primer argumento y la versión actualmente instalada como el segundo argumento. Esto
pasa antes de Odoo incluso miradas en el resto del código el addon define, así que puedes
suponer nada cambiado en vuestro diseño de base de datos comparó a la versión anterior.
Después de todo pre-emigrar las funciones corridas exitosamente, Odoo carga los
modelos y dato declared en el addon, los cuales pueden causar cambios en el diseño de
base de datos. Dado rebautizamos liberación_de fecha en pre-migrate.py, Odoo justo
creará una columna nueva con aquel nombre, pero con el tipo de dato correcto.
Allí ha más...
En ambos el pre- y correo-pasos de migración, sólo tienes acceso a un cursor, el cual no es
muy conveniente si estás utilizado a Odoo environments. Pueda dirigir a resultados
inesperados para utilizar modelos al llegar a este punto, porque en el pre- paso, el addon
los modelos no son todavía cargados y también, en el correo- paso, los modelos definieron
por addons dependiendo de el actuales addon no es todavía cargado también. Pero si this
no es un problema para ti, tampoco porque quieres utilizar un modelo vuestro addon no
toca o un modelo para qué sabes el antedicho no es un problema, puedes crear el entorno
estás utilizado a por escribir el siguiente:
De openerp importación SUPERUSER_ID
de openerp.api Entorno de importación
Ve también
Cuándo escribiendo guiones de migración, a menudo serás afrontado con tareas repetitivas
como checrey si una columna o la mesa existe, rebautizando cosas, o mapeo algunos valores
viejos a valores nuevos. Está frustrando y error-prone para reinventar la rueda aquí; considera
utilizar https://github. com/OCA/openupgradelib Si puedes proporcionar la
dependencia extra.
232
10
Seguridad de
acceso
En este capítulo, veremos cómo a:
Para concisely conseguir el punto a través de, las recetas en esta marca de capítulo
adiciones pequeñas a un módulo de existir. Escogimos utilizar el módulo creado por las
recetas en Capítulo 3, Creando Odoo Módulos. A mejor seguir los ejemplos aquí, tendrías
que tener aquel módulo creado y a punto para utilizar.
Preparándose
Esta receta supone tienes un caso a punto, con el mi_módulo disponible, cuando descrito
en Capítulo 3, Creando Odoo Módulos.
4. Añade dentro del dato XML elemento las etiquetas récord para los dos grupos
nuevos:
<Récord id="modelo_de usuario_de biblioteca" de
grupo="res.Nombre"> <de nombre de campo="de
grupos">campo</de Usuario>
<Categoría de nombre="del campo_id"
ref="base.Biblioteca_de categoría_del
módulo"/>
<Nombre de campo="implicó_ids"
eval="[(4, ref('base.groArriba_usuario'))]"/>
</Récord>
Si nosotros upgrade el addon módulo, estos dos registros serán cargados y seremos
capaces de verles en los Usuarios de Encuadres de opción | de carta | Grupos:
How Trabaja...
Addon Los módulos están organizados en áreas funcionales, o aplicaciones importantes,
como Finanza & de Contabilidad, Ventas, o Recursos Humanos. Estos están definidos por
la llave de categoría en el manifestar archivo.
Si un nombre de categoría no existe todavía, seaun utomatically creó. Para comodidad, una
base.Categoría_de categoría_<del módulo> XML ID también será generado para
el nombre de categoría nuevo en lowercase letras, reemplazando espacios con
underscores. Esto es útil de relacionar grupos de seguridad con categorías de aplicación.
En nuestro ejemplo, utilizamos el nombre de categoría de la Biblioteca, y genere una
base.Biblioteca_ de categoría_del módulo XML identificador.
Por convention, el dato archiva añadir la seguridad relacionó los elementos tendrían
que ser colocados dentro de un subdirectorio de seguridad.
El orden en qué los archivos está declarado en el atributo de dato es importante, desde
entonces no puedes utilizar un identificador antes de que ha sido definido. Podemos
whormiga para utilizar referencias en vistas para los grupos de seguridad habíamos
definido, así que es más para colocar el archivo de dato de la seguridad en la parte
superior de la lista antes del ACL archivos de definición y la otra interfaz de usuario archivos
de dato.
235
Seguridad de acceso
Seguridad groups tendría que ser añadido utilizando un archivo de XML. Pueda añadir
registros que queremos ser customizable por los usuarios de fin. Para impedir aquellos
cambios posibles que son perdidos en un módulo upgrade, tendríamos que añadir
aquellos registros dentro de un <dato noupdate="1"> elemento. Esto es normalmente
el caso para seguridad reglas récord, hablados en el Límite el acceso récord que utiliza
receta de reglas récord más tarde.
Pero para grupos de seguridad, la práctica utilizada en Odoo núcleo addon los módulos es
para tenerles definido dentro de un <dato noupdate="0"> elemento. Esto significa que
they será reescrito en un módulo upgrade, y así que no tendría que ser directamente
personalizó. Customization En cambio tendría que ser hecho por crear grupos nuevos que
hereda del default unos.
También, los permisos de acceso concedieron por grupos de seguridad son acumulables. Un
usuario tiene algún permiso en cualquier de los grupos pertenece a (directamente o
implicado) concede que permiso.
Algunos grupos de seguridad están mostrados en la forma de usuario como caja de
selección en vez de individual checkboxes. Esto pasa cuándo el implicó los grupos sonen t él
categoría de aplicación misma y es linearly interrelacionado a través de implicado_ids . Por
ejemplo, Grupo Un tiene implicado Grupo B, y Grupo B ha implicado Grupo C.
Nota que las relaciones definieron en los campos de preceder también tienen relaciones
inversas que puede ser editared en el relacionó modelos, como grupos de seguridad y
usuarios.
Poniendo valores encima campos de referencia, como categoría_id e implicado_ids,
está hecho utilizando el relacionado graba XML IDs y algunos sintaxis especial.
236
Capítulo 10
Para Muchos2una relaciones, the ref el atributo suele enlace con el registro con el XML
correspondiente ID. Para Uno2muchos campos, como implicados_ids, el eval el atributo
está utilizado con una lista de tuple órdenes. Por ejemplo, el tuple 4 cuando el primer
elemento añade las referencias en el elemento próximo o elementos. Esta sintaxis está
explicada en detalle en Capítulo 9,
Dato de módulo.
Allí ha más...
También digno de mención es la base especial.Grupo_ningún_un grupo de
seguridad. En el anterior Odoo versiones, esté utilizado para adelantó las características
escondidas por default, y sólo hechos visibles cuándo la bandera de Características
Técnica estuvo activada. Desde entonces versión 9.0 esto ha cambiado, y aquellas
características están hechas visibles mientras el Modo de Desarrollador está activado.
Los permisos de acceso concedieron por grupos de seguridad son acumulables sólo. TAquí
es ninguna manera de negar un acceso dado por algún grupo. Esto significa un grupo
manualmente creado para personalizar los permisos tendrían que heredar del grupo más
cercano con menos permisos que aquellos pretendidos (si cualquier), y entonces añadir
todos los permisos restantes necesitaron.
Los grupos también tienen disponibles estos campos adicionales:
fCartas (elcampo_de accesode la carta): Estos son los elementos de carta el grupo
tiene acceso a fVistas (elcampo_de accesode la vista): Estos son el UI ve el grupo
tiene acceso a
fDerechos de acceso (elacceso_de modelofield): Estos son el acceso
tiene en modelos,detallados en el Añadir acceso de seguridad a receta de
modelos
fReglas (elcampo_de gruposde la regla): Estos son el acceso de nivel récord
gobierna aquello aplica a el grupo, detallado en el Límite el acceso récord que
utiliza reglas récord recipe
f Notas (el campo de comentario): Esto es una descripción o texto de comentario para el
grupo
237
Seguridad de acceso
However, modelos sin ACLs provocará un mensaje de registro del aviso encima cargando,
informando sobre el desaparecido ACL definiciones: La biblioteca de modelo.El libro tiene
ninguno reglas de acceso, considera añadir un. Para evitar que, tendrías que mirar para
tales mensajes durante pruebas, y antes de que publishing vuestra marca de código seguro
te corrido las pruebas con el demo usuario más que admin.
Tan, para modelos nuevos para ser utilizables por no-admin usuarios, necesitamos definir
sus listas de control de acceso de seguridad, de modo que Odoo sabe cómo les tenga que
acceder y lo que operations cada grupo de usuario tendría que ser dejado.
Preparándose
Tomaremos el módulo creado en Capítulo 3, Creando Odoo Módulos y añadir a él el
desaparecido ACLs.
238
Capítulo 10
Tenemos que entonces upgrade el módulo para tener estos ACL los registros añadieron a
nuestro Odoo base de datos. Más importantly, si firmamos en a una base de datos de
manifestación que utiliza el demo usuario, tendríamos que ser capaces de acceder la opción
de carta de la Biblioteca sin cualesquier errores de seguridad.
Cómo trabaja...
Las listas de control de acceso de seguridad están almacenadas en el núcleo
ir.Modelo.Modelo de acceso. Justo necesitamos añadir a él los registros que describen los
derechos de acceso pretendidos para cada grupo de usuario.
Cualquier tipo de archivo de datos haría, pero la práctica común es para utilizar un CSV
archivo. El archivo puede ser colocado anywhere dentro del addon directorio de módulo,
pero la convención es para tener all la seguridad relacionó archivos dentro de un
subdirectorio de seguridad.
El primer paso en nuestra receta declara este archivo de dato nuevo al manifestar y el segundo
añade el archivo que describe las reglas de control de acceso de seguridad. El CSV el archivo
tiene que ser nombrado después del modelo where los registros serán cargados, así que el
nombre utilizó no es justo una convención y es obligatorio.
Si el módulo también crea grupos de seguridad nueva, su archivo de dato tendría que ser
declarado antes del ACLs' archivo de dato, desde entonces les puedes querer utilizar para
el ACLs y tan ya tienen que ser creados cuándo el ACL el archivo está procesado.
Las columnas en el CSV el archivo es como sigue:
fid: Esto es el XML ID identificador interno para esta regla. Cualquier nombre
único dentro delmódulo haría, pero la convención es para utilizar
modelo_<de acceso>_<groarriba>.
fNombre: Esto es un título para la regla de acceso y, por convención, la práctica
común esutilizar un acceso.<Modelo>.<Nombre> de grupo.
fModelo_id:id: Esto es el XML ID para el modelo. Odoo Automáticamente asigna
talun ID a modelos con un nombre de modelo_<del formato>, utilizando el
nombre de _el modelo con underscores en vez de puntos. Si el modelo estuvo
creado en un diferente addon módulo, un plenamente cualificado XML ID está
necesitado, incluyendo el nombre de módulo.
fGrupo_id:id: Esto es el XML ID para el grupo de usuario. Si dejó vacío, él applies
a todosusuarios. El módulo de base proporciona algunos grupos básicos,
como base.Usuario_de grupo, para todos los empleados y base.Sistema_de
grupo para el usuario de administración. Otras aplicaciones pueden añadir sus
grupos de usuario propios.
f perm_Leyó: Esto puede leer los registros de modelo (0 o 1).
fperm_Escribe: Esto puede actualizar los registros de
modelo (0 o 1).fperm_Crea: Esto puede añadir registros
de modelo nuevo (0 o 1).fperm_unlink: Esto puede
eliminar registros de modelo (0 o 1).
El CSV archivo utilizamos añade acceso único leído a los Recursos Humanos | Employee
grupo de seguridad estándar, y lleno escribe acceso al grupo | de Encuadres de la
Administración.
239
Seguridad de acceso
Algunas personas lo encuentran más fáciles de utilizar esta interfaz de usuario para
definir ACLs y entonces utilizar la característica de exportación para producir un CSV
archivo.
Allí ha más...
Haga sentido para nosotros para dar este permiso al usuario de Biblioteca y grupos de director
de la Biblioteca definieron en el Crear Grupos de seguridad y asignarles a receta de Usuarios. Si
seguiste que receta, es un ejercicio bueno a entonces seguir este un, adaptando el grupo
identifiers al
Biblioteca unos.
Es importante de notar que el acceso lista proporcionado por el addon los módulos no
tendrían que ser directamente personalizados, desde entonces serán reloaded en el
módulo próximo upgrade, destruyendo cualquier customization que podría haber sido
hecho de the GUI.
240
Capítulo 10
Para personalizar ACLs, dos aproximaciones pueden ser utilizadas. Uno es para crear la
seguridad nueva agrupa aquello hereda del proporcionado por el módulo y añadir permisos
adicionales encima lo, pero esto deja sólo para añadir, no para sacar. Una aproximación
más flexible puede ser a uncheck la bandera Activa a falso en el particular ACL líneas, para
inutilizarles. No es visible por default, así que necesitamos editar la vista de árbol para
añadir el <nombre de campo="columna" /> activa. También podemos añadir nuevos
ACL líneas para añadiritional o permisos de sustitución. En un módulo upgrade, el
deactivated ACLs no será reactivado y el añadido ACL las líneas no serán afectadas.
Es también valor notando que ACLs sólo aplicar a modelos regulares y no necesita para ser
definido para Abstracto o Transi ent modelos. Si definido, estos serán desatendidos y un
mensaje de aviso será provocado al registro de servidor.
Aquello es. Ahora upgrade el añadirencima módulo para los cambios en el modelo para
tener lugar. Si firmas en con un usuario sin acceso de configuración del sistema, como
demo en una base de datos con dato de manifestación, la forma de libros de la Biblioteca
no mostrará el campo.
Cómo trabaja...
Campos con el groups el atributo es especialmente manejado para comprobar si el
usuario pertenece a cualquiera de los grupos de seguridad indicó en el atributo, y si no
saca él de UI vistas y ORM operaciones para el usuario.
Nota que esta seguridad no es superficial. El campo no es enly escondido en la interfaz de
usuario, pero es también hecho inutilizable al usuario en el otro ORM operaciones, como
leídos y escribir . Esto es también cierto para el XML-RPC o JSON-RPC llamadas.
241
Seguridad de acceso
Ser prudente cuándo utilizando estos campos en business lógica, o encima cambiar UI
acontecimientos (@api. onchange Métodos); pueden levantar errores para usuarios
sin acceder al campo. Un workaround para este es para utilizar elevación de privilegio,
como el sudo() método de modelo o el computar_sudo atributo de campo para
computó campos.
El valor de grupos es una cuerda conteniendo una coma lista separada de válido XML
IDs para grupos de seguridad. La manera más sencilla de encontrar el XML ID para un
grupo particular es a navigate a su forma, en Grupos | de Usuarios | de los Encuadres, y
entonces acceder la Vista Metaopción de dato del depurar carta, cuando mostrado en el
siguiente screenshot:
Allí ha más...
En algunos casos, necesitamos un campo para ser disponible o no dependiendo de
condiciones particulares, como los valores en un campo particular, gusta etapa_id or
estado. Esto es normalmente manejado en el nivel de vista que utiliza atributos como
estados o attrs , a dinámicamente exhibición o esconder el campo según condiciones
seguras. Puedes referir a Capítulo 8, Backend Vistas para una descripción detallada.
Nota que estos techniques trabajo en el nivel de interfaz del usuario sólo y no proporciona
seguridad de acceso real. Para aquel te tendría que añadir controles en la capa de lógica
empresarial. Cualesquiera añaden métodos de modelo decoraron con @apremia ,
implementando las validaciones concretas pretendieron, o ext acabar el crear, escribe,
o unlink métodos para añadirles lógica de validación. Puedes conseguir más idea encima
cómo para hacer este en Capítulo 5, Lado de Servidor Básico Lógica Empresarial.
242
Capítulo 10
Preparándose
Esta receta supone tienes un caso a punto, con mi_ módulo disponible, cuando descrito en
Capítulo 3, Creando Odoo Módulos.
243
Seguridad de acceso
Cómo trabaja...
Las reglas récord son dato justo graba cargado al ir.Modelo de núcleo de la regla. Mientras el
archivo que les añade podría ser anywhere en el módulo, la convención es para él para ser en el
subdirectorio de seguridad. Es común de tener un archivo de XML solo con ambos grupos de
seguridad y rereglas de cordón.
Grupos diferentes, en los módulos estándares, las reglas récord están cargadas en una sección
de dato con el noupdate="1" atributo. Con este, aquellos registros no serán reloaded en un
módulo upgrade, significando que manual customizations encima les es seguro y wenfermo
sobrevive más tardío upgrades.
Para quedarse compatible con los módulos oficiales, también tendríamos que tener nuestras
reglas récord dentro de un
<Dato noupdate="1"> sección.
Las reglas récord pueden ser vistas del GUI en los Encuadres de opción de la carta |
Seguridad | Técnica | Reglas Récord, cuando mostrados en el siguientes screenshot:
244
Capítulo 10
La primera regla récord creamos era para el grupo de seguridad del Empleado. Utiliza
la expresión de ámbito [('crear_uid', '=', user.id)] para seleccionar sólo
aquellos libros donde el usuario de creación es el usuario actual . Así, sólo serán
capaces de ver los libros crearon por ellos.
Las expresiones de ámbito utilizaron en las reglas récord corridas en el lado de servidor que
utiliza ORM objetos.
Debido a este, notación de punto puede ser utilizada en los campos en el lado izquierdo (el
primer tuple elemento). El correcto side (tercio tuple elemento) es una expresión de Pitón,
evaluado en un contexto habiendo disponible el usuario objeto récord, para el usuario actual,
y la biblioteca de Pitón del tiempo.
Para el grupo de seguridad de los encuadres, lo queremos para ser capaces de ver todos los
libros, independientes de quién les creó en la base de datos. Desde entonces hereda el grupo
de Empleado, a no ser que nosotros algo aproximadamente lo, también sea capaz de ver sólo
los libros crearon por él.
El varios (no global) las reglas récord están unidas juntas utilizando el U operador lógico: cada
regla añade acceso y nunca saca el acceso. Para el Director de Biblioteca para tener acceso a
todos los libros, podemos añadir a él una regla récord para añadir el acceso a libros creó por
otros usuarios, gusta
Esto: [('crear_uid', '!=', user.id)].
Escogimos hacer differently y utilizar la regla especial [(1, '=', 1)] a incondicionalmente dar
acceso a todos los registros de libro. Mientras esto puede parecer redundando, recuerda que
otherwise la regla de usuario de la Biblioteca puede ser personalizada en una manera que
mantendría algunos libros fuera de lograr al
Settings Usuario. Es especial porque el primer elemento de un ámbito tuple tiene que ser
un nombre de campo; este caso exacto es el caso único donde aquello no es cierto.
Allí ha más...
Cuándo una regla récord no es asignada a cualquier grupo de seguridad, está
marcado como Global y está manejado de manera diferente de las otras reglas.
245
Seguridad de acceso
Las reglas récord globales tienen un efecto más fuerte que group nivela reglas récord, y
restricción de acceso puesto que aquellos pueden no override. Técnicamente, están
unidos con un Y operador. En los módulos estándares, suelen implementa multi-
acceso de seguridad de la compañía, de modo que cada usuario puede ver sólo su
compañía's dato.
En resumen, regular no las reglas récord globales están unidas junto con un U operador: están
añadidos juntos y un registro es accesible si cualquiera de la regla concede que acceso. Las
reglas récord globales entonces añaden restricciones al acceso dado por el regular reglas récord,
utilizando un Y operador. Las restricciones añadieron por las reglas récord globales no pueden
ser overridden por reglas récord regulares.
Preparándose
Esta receta utiliza mi_módulo descrito en Capítulo 3, Creando Odoo Módulos.
Necesitaremos grupos de seguridad para trabajar con, así que también necesitas tener
seguido el Añadir acceso de seguridad a receta de modelos.
En esta receta, alguna necesidad de identificadores para referir al addon el nombre técnico
del módulo. Supondremos que es mi_módulo . En caso estás utilizando un nombre
diferente, reemplazar mi_módulo con el nombre técnico real de vuestro addon módulo.
1. Para añadir el necesitado dependency y los archivos de dato de XML nuevos, editar el
__openerp__.py Manifiesta así:
# -*- Codificación: utf-8 -*-
{ 'Nombre': 'código de Recetario',
246
Capítulo 10
'Categoría':
'Biblioteca', 'depende':
['base_setup'], 'dato': [
Esecurity/ir.Modelo.Acceso.csv',
esecurity/seguridad_de
biblioteca.xml', 'libro/de
biblioteca_de las vistas.xml',
'vistas/res_config_encuadres.xml
',
],
}
3. Para hacer la fecha de liberación del libro visible sólo cuándo esta opción está
habilitada, editamos el campo definition en los modelos/library_book.py
archivo:
# Clase LibraryBook(modelos.Modelo):
# ...
Campos_de liberación = de la
fecha.Fecha( esFecha de
arrendamiento',
Los grupos= soyy_módulo.Liberación_de grupo_data')
5. Para extender el brujo de configuración del núcleo que añade opciones nuevas a
él, añadir los modelos/ res_config_settings.py archivo con este código:
# -*- Codificación: utf-8 -*-
De openerp modelos de importación, fields
Clase ConfigSettings(modelos.TransientModel):
_Hereda = 'base.config.Encuadres'
campos_de fechas_de liberación = de
grupo.Booleano(
"Dirige fechas de liberación del libro",
grupo='base.Usuario_de grupo', el
grupo_implicado= soyy_módulo.Liberación_de
grupo_data')
Campos_de nota = del módulo.Booleano("Insaplicación de Notas
altas")
247
Seguridad de
acceso
Después de que upgrading el addon módulo, el dos new opciones de configuración tendrían
que ser disponibles en
Encuadres | Encuadres Generales. La pantalla tendría que parecer esto:
Cómo trabaja...
El módulo de base del núcleo proporciona un res.config.Modelo de encuadres que
proporciona la lógica empresarial detrás optaactivación de ión. La base_setup addon el módulo lo
utiliza para proporcionar la varias configuración básica opciones para hacer disponibles en una
base de datos nueva. También hace disponible el
Encuadres | carta de Encuadres Generales.
El primer paso de receta añade la base_setup addon módulo a las dependencias, desde
entonces proporciona la base.config.Modelo de encuadres queremos uso. También añade
un añadiritional
Archivo de dato del XML necesitaremos añadir las opciones nuevas a la forma de Encuadres
General.
El campo_ de opción del grupo tendría que tener un atributo_de grupo implicado y ser una
cuerda que contiene una coma lista separada de XML IDs para los grupos de seguridad para
activar cuándo está habilitado. El
XML yoDs tiene que ser en la forma completa con identificador de punto de nombre de
módulo nombre.
También podemos proporcionar un atributo de grupo para especificar para qué seguridad
agrupa la característica será habilitada. Sea para todo el empleado basó grupos, si ningún
grupo está definido. Por ello no aplicarán a grupos de seguridad del portal, desde entonces
estos no heredan en el grupo de seguridad de base de empleado, como la otra seguridad
regular grupos.
El mecanismo detrás de la activación es bastante sencillo: añade el grupo de seguridad
en el atributo de grupo al implied_grupo, por ello haciendo la característica
relacionada visible a los usuarios correspondientes.
Amonestación:
Unchecking La caja uninstall el módulo sin advertir, los cuales
pueden causar pérdida de dato (los modelos o los campos
sacados y dato de módulo sacado como consecuencia). Para
evitar unchecking la caja by accidente, el seguro_uninstall
módulo comunitario (de https://github.com/oca/server-tools )
incita para una contraseña antes de que uninstalling el addon
módulo.
El último paso de la receta añade las opciones a la vista de forma de Encuadres General,
justo antes del
Grupo de Integración del Google, habiendo nombre="google".
250
Capítulo 10
Allí ha más...
Encuadre de configuración también puede tener los campos nombraron con el default_
prefijo. Estos cuando habiendo un valor lo pondrá uns un global default. El campo de
encuadres tendría que tener un default_atributo de modelo para identificar el modelo
afectó, y el nombre de campo después del default_ el prefijo identifica el campo del
modelo que habrá puesto el default valor.
Además, campos con ninguno de los tres prefijos mencionó puede ser utilizado para otros
encuadres, pero necesitarás implementar la lógica para poblar sus valores, utilizando
consigue_default_ el nombre prefijó métodos, y para actuar cuándo sus valores están
editados, utilizando nombre_ de conjunto prefijó métodos.
Para quienes gustarían ir más profundos a detalles de encuadres de la configuración, la
documentación mejor disponible es en Odoo es
./openerp/addons/Base/res/res_config.py archivo.
251
11
Internacionalizació
n
En este capítulo, cubriremos los temas siguientes:
Preparándose
Necesitaremos tener el Modo de Desarrollador activó. Si no es, activa él en el
Odoo Aproximadamente diálogo.
253
Internacionalización
254
Capítulo 11
Los usuarios pueden también puestos estas configuraciones ellos a través de la opción de
carta de las Preferencias, disponible cuándo ellos clic en el nombre de usuario en el derecho
superior de la ventana de cliente de la web.
Cómo trabaja...
Los usuarios pueden tener su lengua propia y timezone preferencias. El anterior suele
traducir el texto de interfaz del usuario a la lengua escogida y aplicar convenciones locales
para el flotador y campos monetarios. El último suele exhibición el datetime campos en el
correctos timezone.
Antes de una lengua está hecha disponible para los usuarios para seleccionar, tenga que
ser instalado con la Carga una característica de Traducción. La lista de lenguas
instaladas puede ser vista con los Encuadres | Translations | opción de carta de las
Lenguas.
Cada Odoo addon el módulo es responsable para proporcionar sus recursos de traducción
propios que tendría que ser colocado dentro de un i18n subdirectorio. El dato de cada
lengua tendría que ser en un .po Archivo. Siguiendo nuestro ejemplo, para el
españollangua ge, el dato de traducción está cargado del es_es.po archivo de dato.
255
Internacionalización
Odoo También apoya la idea de lengua de base. Por ejemplo, si tenemos un es.po
archivo para español y un es_mx.po archivo para español mexicano, entonces es.po está
detectado como la lengua de base para es_mx.po. Cuándo la lengua española mexicana
está instalada, ambos archivos de dato están cargados; primero el para la lengua de base y
entonces la lengua concreta está instalada. Así, el archivo de traducción de lengua concreto
sólo needs para contener las cuerdas que es concreto a la variante de lengua, español
mexicano en nuestro ejemplo.
El i18n el subdirectorio es también esperado para tener <un nombre_de
módulo>.Archivo de tarro, proporcionando una plantilla para traducciones y conteniendo
todo el translatable cuerdas. Las cuerdas de traducción de la Exportación a una receta de
archivo explica cómo para exportar el translatable cuerdas para generar este archivo.
Cuándo una lengua adicional está instalada, los recursos correspondientes están
cargados de todo instalados addon módulos y almacenados en el T ranslated modelo de
Plazos. Su dato puede ser visto (y editado) con los Plazos | de Aplicación | de
Traducciones de Encuadres | Tradujeron opción de carta de los Plazos.
Archivos de traducción para las lenguas instaladas son también cargados cuándo un
nuevos addon el módulo es instalado o un existing addon el módulo es upgraded.
Allí ha más...
Archivos de traducción pueden ser reloaded sin upgrading el addon módulos por repetir la
Carga una acción de Traducción. Esto puede ser utilizado en caso has actualizado archivos
de traducción y no quiere pasar por elt rublo de upgrading los módulos (y todas sus
dependencias).
Si el Overwrite Existiendo Plazos checkbox queda vacío, sólo la cuerda traducida nueva está
cargada. Así, el cambió la cuerda traducida no será cargada. Control la caja si quieres el ya
existiendo traducciones a también ser cargados y overwrite las traducciones actualmente
cargadas.
El anterior checkbox existe porque podemos hacer nuestras traducciones concretas que
editan Encuadres
| Plazos | de Aplicación de las traducciones | Tradujeron Plazos, o utilizando el Técnicos
Translation opción de atajo en el Depurar carta. Las traducciones añadidas o modificó de este
modo no será overwritten a no ser que la lengua es reloaded con el Overwrite Existiendo Plazos
checkbox habilitó.
Pueda ser útil de saber que el addon los módulos también pueden tener un
i18n_subdirectorio extra con traducciones extras. La secuencia de cargar para los
archivos de traducción es: el .po Archivos en el i18n subdirectorio, primero para la
lengua de base y entonces para la lengua; entonces el .po Archivos en el
i18n_subdirectorio extra, primero para la lengua de base y entonces para la lengua. La
última traducción de cuerda cargada es el aquello prevalece.
Ve también
La lista de códigos de lengua puede ser vista en el código de fuente; en el
odoo/openerp/herramientas/ misc.py archivo, buscar la TODA_variable de LENGUAS.
El GitHub el enlace para el archivo es
https://github.com/odoo/odoo/blob/9.0/openerp/tools/misc.py.
256
Capítulo 11
Preparándose
Necesitaremos tener el Developer el modo activó. Si no es, activa él en el Odoo
Aproximadamente diálogo.
2. Editar los encuadres de lengua. Para cambiar la fecha al formato de ISO, Formato de
Fecha del cambio a %Y-%m-%d , y para cambiar el número format para utilizar una coma
como decimal separator, modificar el Decimal Separator y Miles Separator campos
consiguientemente.
257
Internacionalización
Cómo trabaja...
Cuándo firmando en y creando un nuevo Odoo sesión de usuario, la lengua de usuario
está comprobada ent él preferencias de usuario y puestos en el lang llave de contexto.
Esto es entonces utilizado a formato las producciones apropiadamente: los textos de
fuente están traducidos a la lengua de usuario, y las fechas y los números son formatted
según la lengua actual locale encuadres.
Allí ha más...
Procesos de lado del servidor son capaces de modificar el contexto en qué acciones está
corrido. Por ejemplo, para conseguir un conjunto récord donde las fechas son formatted según
el formato inglés independiente de la preferencia de lengua del usuario actual, podrías hacer
el siguiente:
en_Registros = self.Con_contexto(lang='en_EN').Búsqueda([])
Para más detalles, refiere a Capítulo 6, Desarrollo de Lado de Servidor Adelantado receta de
Técnicas
Llamando un método con un contexto modificado.
Preparándose
Necesitamos tener el Developor el modo activó. Si no es, activa él en el Odoo Aproximadamente
diálogo.
3. Una lista de los plazos de traducción disponibles para aquella vista serán
mostrados. Edita Valor de Traducción en una línea para cambiar (o añadir) su texto
de traducción. Si buscando una cuerda de fuente particular, uso los filtros de lista
para angostar abajo el mostró textos:
259
Internacionalización
4. Navigate Otra vez a la opción de carta de Grupos de Usuario, abre uno de los registros
de grupo en la vista de forma, y el clic encima Edita:
Cómo trabaja...
Tradujo los plazos están almacenados en la mesa de base de datos para el modelo
ir.Traducción. La opción de Traducción Técnica en el Depurar la carta proporciona un
acceso rápido a aquellos plazos, en contexto con la vista actualmente seleccionada.
De modo parecido, el modelo fields con translatable el contenido presenta un icono para
acceder la lista de las lenguas instaladas y para poner el valor apropiado para cada
lengua.
Alternativamente, los plazos de traducción pueden ser accedidos de los Encuadres carta
superior, utilizando el
Traducciones | AppliPlazos de catión | Tradujeron opción de carta de los Plazos. Aquí
podemos ver todos los plazos disponibles para nuestro caso, pero tendría que necesitar
utilizar filtros de dato para localizar los plazos podríamos ser interesados en.
Allí ha más...
Junto al Traducido Denomina opción de carta, también encontramos el Sincronizar opción
de Plazos. Seleccionándolo mostrará una ventana de diálogo para proporcionar la lengua
deseada, y entonces lanzará el proceso para extraer translatable cuerdas del instalados
addon módulos y añadir cualquier nuevo unos al Tradujo Plazos table. Es equivalente a
actuar la Traducción de Exportación seguida por los pasos de Traducción de la Importación
describieron más tempranos.
Esto puede ser útil después de cambiar algunos modelos o vistas, para tener las cuerdas
nuevas añadieron de modo que les podemos traducir.
También pueda seruso d para poblar las cuerdas del en_EE.UU. default lengua.
Podemos entonces uso de marca de los plazos de traducción para reemplazar los textos
ingleses originales con nuevos unos, mejores para el vocabulario empresarial concreto del
usuario de fin.
260
Capítulo 11
Preparándose
Necesitamos tener el Modo de Desarrollador activó. Si no es, activa él en el Odoo
Aproximadamente diálogo.
3. Una vez el proceso de exportación es completo, una ventana nueva será mostrada,
con un enlace para descargar tarchive y algunos consejo adicional:
Cómo trabaja...
The Característica de Traducción de la exportación dos cosas: primero extrae el
translatable cuerdas de los módulos de objetivo, añadiendo el nuevos unos en el
ir.Modelo de traducción, y entonces crea un archivo con los plazos de traducción. Esto
puede ser hecho ambos del cliente de web y la interfaz de línea de la orden.
Cuándo exportando del cliente de web, podemos escoger a cualquier exportación una
plantilla de traducción vacía – un archivo con las cuerdas para traducir junto con
traducciones vacías, o exportar una lengua, resultando en un archivo con el strings para
traducir junto con la traducción ya hecha para la lengua seleccionada.
Los formatos de archivo disponibles es CSV, PO, y TGZ. El TGZ formato de archivo exporta un
archivo comprimido que contiene un nombre de estructura <del directorio>/i18n/
con el PO o archivo de TARRO.
262
Capítulo 11
El CSV el formato puede ser útil de actuar las traducciones que utilizan un spreadsheet, pero el
formato para utilizar en el addon los módulos es el PO archivos. Estos están esperados para ser
colocados dentro del i18n subdirectorio, y si así que es automáticamente cargado una vez la
lengua correspondiente está instalada.
Cuándo exportando estos PO archivos, tendríamos que exportar sólo un módulo a la vez. El
PO el archivo es también un formato popular apoyado por herramientas de traducción, como
Poedit.
Las traducciones también pueden ser exportadas directamente delc ommand línea,
utilizando el --i18n-opción de exportación. Los espectáculos de receta cómo para extraer
ambos los archivos de plantilla y los archivos de lengua traducidos.
En Paso 4 de la sección anterior, exportamos un archivo de plantilla. El --i18n-opción de
exportación espera el camino y el nombre de archivo para exportar. Mente que la extensión de
archivo está requerida para ser cualquier CSV, PO, o TGZ. Esta opción requiere el -d opción,
especificando la base de datos para utilizar.
El --opción de módulos es también necesitada para indicar el addon módulos para exportar.
Nota que el --parón-after-init la opción no es necesitada, desde la orden de
exportación automáticamente regresa a la línea de orden cuándo acabada.
Esto exporta un archivo de plantilla, aquello en un módulo está esperado para tener la
extensión de TARRO. Cuándo trabajando en un módulo, después de la operación de
exportación normalmente queremos mover el exportados PO archivo al módulo i18n
directorio con un <módulo>.Nombre de tarro.
En Paso 5, el --opción de lengua era también utilizó. Con él, en vez de un archivo de
traducción vacío, el tradujo los plazos para la lengua seleccionada eran también exported.
Uno utiliza caso para este es para actuar algunas traducciones a través de la interfaz de
usuario de cliente de web que utiliza la característica de Traducción Técnica, y entonces
exportando e incluyéndoles en el módulo.
Allí ha más...
Cuerdas de texto en vista y definiciones de modelo are automáticamente extraídos para
traducción. Para modelos, el _atributo de descripción, los nombres de campo (el
atributo de cuerda), texto de ayuda, y opciones de campo de la selección están extraídas,
así como los textos de usuario para constreñimientos de modelo (_
Constreñimientos y _sql_constr aints).
Cuerdas de texto para traducir Pitón de interior o código de Javascript no pueden ser
automáticamente detectado, así que el código tendría que identificar aquellas cuerdas,
envolviéndoles interior el underscore función.
En un archivo de Pitón del módulo, tendríamos que hacer seguro está importado con el
siguiente:
De openerp importación _
Entonces pueda ser utilizado wherever un translatable el texto está utilizado con algo así:
_('Hola Mundo')
Para cuerdas que uso información de contexto adicional, tendríamos que utilizar
interpolación de cuerda de la Pitón, así:
_('Infiernoo %s') % 'Mundo'
263
Internacionalización
Nota que la interpolación tendría que ir fuera de la función de traducción. Por ejemplo,
_("Hola %s" % 'Mundo') es mal. Interpolaciones de cuerda también tendrían que ser
preferidas a concatenación de cuerda, de modo que cada texto de interfaz es justo una
cuerda de traducción.
Con respecto al trabajo de traducción manual, cualquier editor de archivo del texto puede
hacer, pero utilizando un archivo que apoya el PO sintaxis de archivo hace el trabajo más
fácil por reducir el riesgo de formatting errores. Tales editores incluyen:
f poedit (https://poedit.net/)
femacs (po-Modo)
(https://www.gnu.org/software/gettext/manual/html_nodo/PO-
Modo.html)
f Lokalize (http://i18n.kde.org/tools)
f Gtranslator (https://wiki.gnome.org/apps/gtranslator)
264
Capítulo 11
4. Si un archivo de traducción existe, añadir las traducciones que puede ser encontrado en
el compendium: $ mv ./addons/Mi_módulo/i18n/es_es.po
/tmp/my_module_es_old.po
$ msgmerge --compendium ./odoo_es.po \ -
o./addons/Mi_módulo/i18n/es_es.po \
/tmp/my_module_es_old.po
./addons/Mi_módulo/i18n/mi_módulo.Tarro $ rm
/tmp/my_module_es_old.po
Cómo trabaja...
Paso 1 de la sección de preceder llamadas odoo.py con el --i18n-opción de exportación.
Necesitas especificar un database en la línea de orden, incluso si uno está especificado en el
archivo de configuración y el --opción de módulos, con una coma lista separada de módulos
para exportar la traducción para.
Paso 2 órdenes de usos del gettext toolbox para crear una traducción compendium para la
lengua escogida, español en nuestro caso. Trabaja por encontrar todo el es_es.po archivos
en el Odoo base de código, y pasándoles al msgcat orden. Utilizamos el --uso-primera
bandera para evitar que choca traducciones ( hay unos cuantos en el Odoo base de código). El
resultado está pasado al msgattrib filtro. Utilizamos el --opción traducida para filtrar fuera
del untranslated entradas y el --opción no borrosa para sacar las traducciones borrosas.
Entonces salvamos el resultado en
odoo_es.po.
265
Internacionalización
Paso 3 crea un archivo de traducción que utiliza el translated valores para los textos ya
encontrados en el compendium. El msgmerge la orden está utilizada con el --compendium
opción para encontrar en el compendium archiva el msgid las líneas que emparejan aquellos en
el archivo de plantilla de la traducción generado en
Paso 1. El resultado está salvado ent él es_es.po archivo.
Si tienes un preexistente .po Archivo para vuestro addon con traducciones te gustaría
preservar, entonces lo tendrías que rebautizar y reemplazar el /dev/null argumento con
este archivo. El rebautizar está requerido para evitar utilizando el mismo archivo ambos para
enpuestos y producción.
Allí ha más...
Esta receta sólo skims las herramientas ricas del GNU gettext toolbox. La cobertura llena es bien
allende el alcance de este libro. Si estás interesado, el GNU gettext la documentación contiene
una riqueza de información preciosa sobre PO manipulación de archivo, y es disponible en
http://www.gnu.
org/Software/gettext/manual/gettext.html.
Preparándose
Necesitamos tener el Modo de Desarrollador activó. Si esningún t, activa él en el Odoo
Aproximadamente diálogo.
Somos también esperados para tener un archivo de traducción para ser importado;
myfile.po, por ejemplo.
1. En la interfaz de usuario de cliente de web, de los Encuadres top la carta selecciona las
Traducciones |
Traducción/de Importación | de Exportación de importación opción de carta.
2. En el diálogo de Traducciones de la Importación, llena fuera del nombre de lengua y el
código de lengua, y seleccionar el archivo para importar. Finalmente, clic en el botón de
Importación para actuar el action.
266
Capítulo 11
Cómo trabaja...
Traducción de importación toma un PO o CSV archivo y carga las cuerdas de
traducción al ir.Mesa de traducción.
La característica de cliente de la web pide el nombre de lengua, pero esto no es utilizado en
el proceso de importación. También tiene un overwrite opción. Si seleccionado, fuerza todas
las cuerdas de traducciones para ser importados, incluso los que ya existen, overwriting les
en el proceso.
En la línea de orden, la importación puede ser hecha utilizando el --i18n-opción de
importación. Tenga que ser proporcionado con el camino al archivo, pariente a un addon
directorio de camino. -d Y --lengua.
(O -l ) es obligatorio. Overwriting También puede ser conseguido por añadir el --i18n-
overwrite opción a la orden. Nota que no utilizamos el --parón-después de que-
init opción. No es necesitado, desde la acción de importación para el servidor cuándo
acaba.
267
12
Automatización
y
Workflows
En este capítulo, mostraremos cubrir los temas siguientes:
Introducción
Las aplicaciones empresariales sonex pected no sólo para almacenar registros, pero también
para dirigir empresarial workflows. Odoo Incluye un workflow motor, pero es cada vez más
utilizado menos en versiones más tardías del producto. En cambio, reglas de automatización y
Kanban los tableros están utilizados siempre que posibles.
El automation las reglas son más pertinentes para customization que para nuevos addon
desarrollo de módulos, pero los desarrolladores todavía tendrían que ser familiares con ellos.
Haciendo así que puede evitar encima-engineered reglas empresariales que podría ser
implementado a través de funcional customizations. Algunos de estas técnicas también
pueden ser utilizadas por usuarios de poder o asesores funcionales para añadir algunos
automatización de proceso más sencillo sin la necesidad de crear hecha de encargo addons.
269
Automatización y Workflows
Preparándose
Para seguir esta receta, necesitarás tener la aplicación de Administración del Proyecto ya
instalada.
Cómo trabaja...
Kanban Es uno de los tipos de vista disponibles, y es capaz de organizar los elementos
agruparon en columnas. Si utilizamos etapas para agrupar los elementos de trabajo,
conseguimos un Kanban tablero. La lista de etapa puede ser configurada para caber las
necesidades concretas del usuario.
Las etapas tendrían que tener un atributo plegado, significando que el corresponding columna
en el Kanban la vista tendría que ser mostrada plegó. El trabajo en elementos de progreso
está esperado para ser en una etapa desdoblada, y rescindió elementos, normalmente
Hechos y Cancelados , tendría que ser en Plegó etapas.
Cada elemento de trabajo tiene una referencia para la etapa es en. Yot también puede
tener un Kanban Estado, representado por una señal de tráfico-como ligero, y una
Prioridad, representado por una estrella. El Kanban las tarjetas también pueden tener
un atributo de color, utilizado para su color de fondo.
271
Automatización y Workflows
Allí ha más...
Las etapas están añadidas a modelos a través de un Mucho2un campo referencing un
modelo de etapa que define las etapas posibles. Encima vistas de forma, pueden ser
representados con la ayuda del statusbar tubería widget. Para más detalles en vistas,
widgets, y diseñando Kanban vistas, puedes referir a Capítulo 8, Backend Vistas.
El complementario Kanban el estado se mantiene con un campo de Selección y su definición
típica es:
kanban_Campos = estatales.Selección(
[('Normal', 'Normal'),('bloqueado', 'Bloqueado'),('hecho',
esady para etapa próxima')],
'Kanban Estatal',
default='normal')
Preparándose
Necesitaremos un Odoo caso con la aplicación de Proyecto instalada. También
necesitaremos el Modo de Desarrollador activó. Si no es, activa él en el Odoo
Aproximadamente diálogo.
Valor: 1
El siguiente screenshot muestra el introdujo valores:
274
Capítulo 12
Cómo trabaja...
Trabajo de acciones del servidor en un Modelo, así que uno de las primeras cosas para
hacer es para elegir el Modelo de Base queremos trabajo con. En nuestro ejemplo,
utilizamos Tareas de Proyecto.
Luego, tendríamos que seleccionar el tipo de acción para actuar. Hay unas cuantas opciones
disponibles:
f Envía el email deja escoger una plantilla de email, y lo utilizará para enviar fuera
de un email cuándo la acción está provocada.
f Gatillo un Workflow Signal hace justo aquello. En Odoo Workflows, las
señales pueden ser provocadas y utilizadas para despedir workflow
f transiciones.
Corrido una Acción de Cliente provoca un cliente o acción de ventana, justo
f gustar cuándo un elemento de carta es clicked.
Crea o Copiar un Registro nuevo te dejas para crear un registro nuevo, en el actual
f o en otro Modelo.
Escribe en un Registro te dejas para poner valores en el actuales o en otro registro.
Ejecuta Código de Pitón te dejas para escribir código arbitrario para ejecutar,
f
cuándo ninguno de las otras opciones es bastante flexible para qué necesitamos.
Para nuestro ejemplo, utilizamos Escribir en un Récord de poner algunos valores en el registro
actual. Ponemos Prioridad a 1 , para protagonizar la tarea, y poner un valor en el campo de
Fecha límite. Esto uno es más interesante, desde el valor a uso está evaluado de una Pitón
expression. Nuestras marcas de ejemplo
Uso del datetime módulo de Pitón (ve https://docs.python.org/2/library/
datetime.html) Para computar tdate tres días de hoy.
Expresión de Pitón arbitraria puede ser utilizada allí, así como en varios de la otra acción
escribe disponible. Para razones de seguridad, el código está comprobado por el
seguro_eval función, implementado en
odoo/openerp/herramientas/safe_eval.py. TSuyo significa que algunas operaciones
de Pitón no pueden ser dejadas, pero esto raramente prueba para ser un problema.
275
Automatización y Workflows
Allí ha más...
El código de Pitón está evaluado en un contexto restringido, donde los objetos siguientes son
available para utilizar:
fenv: Esto es una referencia para el objeto de Entorno, justo
comoself.envEnmétodo de clase.
fModelo:Esto es una referencia a la clase de modelo los actos de acción del
servidor a. En nuestroejemplo, es equivalente a self.env['Proyecto.Tarea] .
f workfAbajo: Esto es una referencia al Odoo workflow objeto de servidor del motor.
fAviso: Esto es una referencia a openerp.Excepciones.Aviso,
dejandopara validaciones que bloque unintended acciones. Pueda ser
utilizado cuando: levanta
Aviso( soyessage!').
fObjetoo obj: This proporciona referencias al registro actual, dejándote para
accedersus valores de campo y métodos.
fRegistro: Esto es una función a mensajes de registro
enir.loggingModelo, dejando paralado de base de datos logging
en acciones.
f datetime, dateutil, y tiempo : Estos provide acceso a las bibliotecas de Pitón.
Preparándose
Utilizaremos mi_módulo introducido en Capítulo 3, Creando Odoo Módulos, definiendo el
Modelo de Libro de la biblioteca. Puedes conseguir aquel código o deprisa crear un
addon alrededor de este modelo:
# -*- Codificación: utf-8 -*-
De openerp modelos de importación,
clase de campos
LibraryBook(modelos.Modelo):
_Nombre = 'biblioteca.Libro'
Campos = de nombre.Char('Título',
requerido=Cierto) campos_de liberación = de
la fecha.Fecha( esFecha de arrendamiento')
Autor_ids = fields.many2muchos( ess.Socio', cuerda='Autores')
<Forma>
<Grupo>
<Nombre de nombre="del campo"/>
<Autor de nombre="del campo_ids"
widget="muchos2mucho_grupo"/> </de etiquetas>
<Grupo>
<Liberación de fecha="de
nombre_de campo"/> </grupo>
</Forma>
277
Automatización y Workflows
Después de instalar estos cambios, tendríamos que ver la pared de mensaje en el fondo de la
forma de Libro de la Biblioteca, y cambios al Título y campos de Fecha de la Liberación
tendrían que ser logged encima lo.
Cómo trabaja...
El Hablar añadirencima (el correo nombre técnico) proporciona el correo.Modelo de
hilo para utilizar en otros modelos empresariales como mixin clase. Nuestros primeros
pasos son para añadir la dependencia de módulo y para tener la biblioteca.Módulo de
libro para heredar características de él.
278
Capítulo 12
Los tipos de mensaje se apellidan Subtipos. El módulo de correo viene con dos subtipos:
discussion mensajes y notas internas. El primero puede provocar notificaciones de email y es
visible a todos los seguidores. El segundo un no provoca notificaciones y sólo puede ser visto por
usuarios en el grupo de seguridad del Empleado. Podemos poner el subtipo cuándo posting
messages utilizando su XML IDs. Para estos dos, el correspondientes XML IDs es
mail.mt_comentario y
mail.mt_Nota.
El subtipo para los mensajes de seguir puede ser cambiado por el _subtipo_de pista()
método.
Recibe un diccionario con los nombres de campo seguidos con changes, y sus valores antes
de los cambios estuvieron hechos. Está esperado para regresar una cuerda con el XML ID
del subtipo para utilizar. Los subtipos proporcionados por el correo addon no necesita el
sufijo de módulo, así que podemos utilizar justos mt_comentario para mensajes de
discusión. Si ningúns pecific el subtipo está regresado, los mensajes utilizarán el default
mt_subtipo de nota.
Los seguidores pueden suscribir a subtipos diferentes, así que son capaces de escoger
cuándo para ser notificados.
Por ejemplo, el Proyecto addon añade subtipos como etapa de cambio de la Tarea o la
tarea es b cerró. Con _subtipo_de pista() , podemos detectar tales acontecimientos e
informarles a través de mensajes con el subtipo apropiado. Dentro de aquel método, self
hace disponible el recordsets implicó en el escribir operación, de modo que subtipos de
mensaje distinto pueden ser seleccionados based en valores récord arbitrarios.
Allí ha más...
Posting Los mensajes pueden ser hechos utilizando el método siguiente:
obj.Correo_de mensaje(texto="de Cuerpo del cuerpo",
Tema="subject", subtipo="mt_ nota")
279
Automatización y Workflows
Los seguidores pueden ser cualesquier socios o canales de mensaje. Para añadir
seguidores, uso el siguiente:
Es razonable de esperar para ser capaz a mensajes de correo o seguir documentos incluso
si el usuario conectado tiene ningún escribir acceso a ellos. Lógica de seguridad especial
está implementada para dejar esto, y estos particular las operaciones están actuadas con
el usuario de Administrador, a través del sudo() ORM método.
Subtipos de mensaje pueden ser dirigidos en los Encuadres carta superior, por navigating a
la carta | de Subtipos | de Email Técnica elemento. Allí podemos inspeccionar los subtipos
de existir y customize les. La descripción es el texto mostrado en el mensaje, y el Default el
campo indica si el subtipo está suscrito por default para los seguidores nuevos.
Los subtipos apoyan un mecanismo de herencia. Es, por ejemplo, utilizado por proyectos
para dejar el followers a automáticamente suscribir acontecimientos en tareas y asuntos,
como la tarea Abrió. Esto está hecho utilizando los campos en el área de Suscripción del
Coche del subtipo:
fElpadrees el subtipo relacionado para ser automáticamente suscribió.
Paraproyecto.Tarea de proyecto Abrió, esto sería el proyecto
.Tarea de tarea Abrió.
fCampo de relaciónes el campo en el modelo relacionado para utilizar.
Paraproyecto.Subtipode tarea,esto es proyecto _id, para el Proyecto
para heredar suscripción de.
Odoo También apoya un indicador de Acción de la Necesidad, espectáculon en el elemento
de carta, para señalar aquella acción está requerida en un número de elementos. Por
ejemplo, está utilizado por el correo addon para mostrar el número de unread mensajes.
Para utilizarlo, nuestro modelo también tendría que heredar ir.needaction_mixin, y el
_needaction_ el ámbito_consigue() el método tendría que ser extendido. Es un
@api.Modelo método estático, significando que no actúa a un recordset. Está esperado
para regresar una expresión de ámbito para soler identificar los elementos que necesitan
acción.
Cuando un ejemplo, para señalar que elementos con un Bloqueados Kanban acción de
necesidad estatal, utilizaríamos el siguientes:
def _needaction_El ámbito_consigue(self):
Regreso [('kanban_estatal', '=', 'bloqueado')]
280
Capítulo 12
Preparándose
Necesitaremos un Odoo caso con la aplicación de Proyecto instalada.
Modelo de base: Tarea
Acción para Hacer: Ejecuta Código
de Pitón
281
Automatización y Workflows
Cómo trabaja...
El Create receta de acciones del servidor proporciona una explicación detallada encima
cómo para crear una acción de servidor en general. Para este tipo particular de acción,
necesitamos elegir el Ejecutar opción de Código de la Pitón y entonces escribir el código
para correr el área de texto.
El código puede haber multiple líneas, cuando es el caso en nuestra receta, y corre en un
contexto que tiene referencias disponibles a objetos como el objeto récord actual o el
usuario de sesión. Las referencias disponibles está descrito en el Crear receta de acciones
del servidor.
El código utilizado computes el número de días de la fecha actual hasta la fecha de fecha
límite, y utiliza que para preparar un mensaje de notificación apropiado. La última línea el
real posting del mensaje en la pared de mensaje de la tarea. El subtipo=
soyt_comentario' el argumento es needed para notificaciones de email para ser
enviados a los seguidores, justo gustar cuándo utilizamos el botón de Mensaje Nuevo. Si
ningún subtipo está dado, mt_la nota está utilizada como default, posting una nota
interna sin notificación, como si utilizamos el Registro un botón de nota interno.
ThAntes de es más...
Acciones de servidor de código de pitón son un recurso potente y flexible , pero tiene algunas
limitaciones compararon al hechos de encargo addon módulos.
Desde el código de Pitón está evaluado en tiempo corrido, en caso de un error el stack el
rastro no es tan informativo und lo puede ser más duro de depurar. Es también no posible
de insertar un breakpoint en el código de una acción de servidor que utiliza las técnicas
mostradas en Capítulo 7, Depurando y Testaje Automatizado, así que depurando
necesidades de ser hechas por utilizar logging declaraciones. Otra preocupación es, cuándo
intentando seguir abajo la causa de un comportamiento en código de módulo, puedes
perder aquello; es probablemente causado por un servidor sction.
Cuándo llevando a cabo un uso más intensivo de acciones de servidor, podemos conseguir
interacciones complejas, así que está aconsejado para planear properly y mantenerles
organizó.
282
Capítulo 12
Preparándose
Para seguir esta receta, necesitaremos tener ambos la aplicación de Administración del
Proyecto y las Reglas de Acción Automatizadas addon ya instalados, y tener el Modo de
Desarrollador activó. También necesitaremos la acción de servidor creada en la Pitón de
Utilizar receta de acciones de servidor de código.
3. Para poner los criterios récord, en la caja de texto de campo de Filtro, justo después
del Seleccionar Reenlace de cordones, puesto una expresión de ámbito válida:
[('fecha límite_de fecha', '!=', Falso), ( estage_id.Pliegue',
'=', Falso)]. Cuándo cambiando a otro campo, información en el número de los
registros que conocen los criterios está actualizado, y el Seleccionar cambios de
enlace de los Registros para Cambiar Selección. Por clicking encima lo podemos
comprobar la lista de registros de los registros que conocen la expresión de ámbito.
283
Automatización y
Workflows
6. El clic encima Salva para salvar la acción automatizada. Actuar los pasos siguientes
para probarlo fuera:
Cómo trabaja...
Acción automatizadas acto en un Modelo, y puede ser provocado cualquiera por
acontecimientos o por condiciones de tiempo. Los primeros pasos son para poner
el Modelo y Cuándo para Correr valores.
Ambos métodos pueden utilizar un filtro para angostar abajo los registros elegibles de actuar la
acción encima. Podemos utilizar un ámbito expression para este. Puedes encontrar detalles
encima escribiendo expresiones de ámbito en Capítulo 8, Backend Vistas. Alternativamente,
puedes crear y salvar un filtro encima tareas de proyecto, utilizando las características de
interfaz del usuario, y entonces copia aquí el ámbito automáticamente generado expression,
seleccionando él de la selección de Conjunto basada en una lista de filtro de la búsqueda.
La expresión de ámbito utilizamos selecciona todos los registros con una Fecha límite no vacía
fecha, en una etapa donde la bandera de Pliegue no es comprobada. Las etapas sin la bandera
de Pliegue están consideradas para ser trabajando en progreso. De este modo, evitamos
provocar notificaciones en tareas que es en el Hecho,
Cancelado, o Cerró etapas.
286
Capítulo 12
Entonces tendríamos que definir la condición de tiempo: el campo de fecha para utilizar y
cuando en cronometrar la acción tendría que ser provocada. El periodo de tiempo puede ser
en minutos, horas, días, o meses, y el número de periodos puede ser positivo, para tiempo
después de la fecha, o negativo, para tiempo antes de la fecha. Cuándo utilizando un
periodo de tiempo en días, podemos proporcionar un Calendario de Recurso que define los
días laborables, y la cuenta de día lo utilizará.
Estas acciones están comprobadas por la Acción de Control Gobierna trabajo planificado.
Nota que por default está corrido cada cuatro horas . Esto es apropiado para acciones que
trabajo en los días o escala de meses, pero si necesitas acciones que trabajo en la hora o
minuto timescales, necesitas cambiar el intervalo de correr a un valor más pequeño.
Las acciones serán provocadas para registros que conocer todos los criterios y de quién
fecha de provocar condición (fecha de campo más el intervalo) es después de la última
ejecución de acción. Esto es con objeto de evitar repetidamente provocando la misma
acción. Y esto es por qué manualmente corriendo la acción de preceder trabajará en una
base de datos donde la acción planificada no fue todavía provocado, pero no podría
trabajar inmediatamente en una base de datos where sea ya corrido por el scheduler.
Una vez una acción automatizada está provocada, el tabulador de Acciones te dices qué
tendría que pasar. Esto puede ser una lista de acciones de servidor, haciendo cosas como
cambiar valores en el registro, posting notificaciones, enviando fuera de e-mails, y tan
encima.
Además, dos operaciones especiales son disponibles. Pone Responsable espera el Modelo
de objetivo para tener un usuario_id campo y pone su valor cuándo la acción está
provocada. Añade los seguidores da una lista de socios para ser añadidos a los seguidores
récord.
Allí ha más...
Estos tipos de automatizó las acciones están provocadas una vez una condición de tiempo
segura está logrado. Esto no es igual tan regularmente repitiendo alguna acción mientras
alguna condición es todavía cierta. Por ejemplo, una acción automatizada no sería capaz de
posting un recordatorio todos los días después de la fecha límite ha superado.
Este tipo de la acción en cambio puede ser actuada por Planificó Acciones, almacenados
en el ir.cron Modelo. Aun así, planificó las acciones no apoyan acciones de servidor;
sólo pueden llamar un existiendo method de un objeto de modelo. Tan, para implementar
una acción hecha de encargo, necesitamos escribir un addon el módulo que añade el
método de Pitón subyacente.
Para referencia, el nombre técnico para el Automatizó Modelo de Acciones es base
.Acción.Regla.
287
Automatización y Workflows
Preparándose
Para seguir esta receta, necesitarás tener la aplicación de Administración del Proyecto
ya instalada. También necesitamos tener el Modo de Desarrollador activó. Si no es,
activa él en el Odoo Aproximadamente diálogo.
3. TÉl encima reglas de actualización te dejan para poner dos filtros récord, antes
de que y después de la operación de actualización. En el Antes texto de campo de
Filtro de Actualización caja, después del Seleccionar enlace de Registros, puesto
una expresión de ámbito válida: [( estage_id.name', '!=', 'Hecho')]. En
la caja de texto de campo de Filtro, puesto el ámbito siguiente: [(
estage_id.name', '=', 'Hecho')], cuando mostrado en el siguiente
screenshot.
Cómo trabaja...
Empezamos por dar un nombre a nuestros iones de actoautomatizados y poniendo el
Modelo trabaja con. Para el tipo de acción, escogemos Encima Actualización, pero el
Encima Creación, Encima Actualización & de Creación, En Deletion, y Basó Encima
opciones de Modificación de la Forma son también posibles.
Luego, tendríamos que definir los filtros para determinar cuándo our la acción tendría que
ser provocada. El Encima acciones de Actualización nos dejan para definir dos filtros: uno
para comprobar antes de que y el otro después de los cambios están hechos al registro.
Esto puede soler expresar transiciones: detectar cuándo unos cambios récord de estatales
Un a estatales B. En nuestro ejemplo, queremos provocar la acción cuándo una tarea no
hecha cambios a la etapa Hecha. El Encima acción de Actualización es el único uno
aquello deja para estos dos filtros; las otras acciones escribe sólo dejar para uno filtra.
290
Capítulo 12
Es hormigade importación para notar que nuestra condición de ejemplo sólo trabajará
correctamente para usuarios de lengua inglesa. Esto es tan porque el Nombre de Etapa es
un translatable campo que puede tener valores diferentes para lenguas diferentes. Tan,
filtros en el translatable los campos tendrían que serun voided o utilizados con cuidado.
Finalmente, creamos y añadir un (o más) acciones de servidor con cualquier queremos
ser hechos cuándo la acción automatizada está provocada. En este caso, escogimos
demostrar cómo para implementar validación hecha de encargo, haciendo uso de un
bacalao de Pitóne acción de servidor que usos la excepción de Aviso para bloquear los
cambios de usuario.
Allí ha más...
En Capítulo 5, Desarrollo de Lado de Servidor Básico, vimos cómo para redefinir el
escribir() métodos de un modelo para actuar acciones oficialmente actualización.
Automatizó acciones enrecor d la actualización proporciona otra manera de conseguir igual,
con algunos beneficios y drawbacks.
Entre los beneficios, es fácil de definir una acción qué está provocado por la actualización
de un almacenó campo computado, el cual es delicado de hacer en código puro. Es también
posible de definir filtros en registros y tener reglas diferentes para registros diferentes, o para
los registros que emparejan diferentes condiciona cuáles pueden ser expresados con
ámbitos de búsqueda.
Pero automatizó las acciones pueden tener las desventajas cuándo comparadas a Pitón código
de lógica empresarial inside módulos. Como preocupación, con pobre planeando esta
flexibilidad rápidamente puede crecer a interacciones complejas, duros de mantener y depurar.
También, el antes y después escribir operaciones de filtro traen algunos elevados, tan para
actuar acciones sensibles esto podría ser un asunto .
Pero, hay unos cuantos workflows todavía utilizado por algunas aplicaciones, tan puede
haber casos donde un desarrollador need para trabajar con ellos. Así que es todavía
pertinente de tener algunos básicos entendiendo de cómo trabajan.
La aplicación de Campañas del Marketing todavía utiliza un sencillo workflow, y lo
utilizaremos para proporcionar esta visión general breve encima les.
Preparándose
Necesitaremos un Odoo instance con demo dato y la Campaña de Marketing addon el módulo
instalado (no que no es una aplicación). También necesitamos tener el Modo de
Desarrollador activó. Si no es, activa él en el Odoo Aproximadamente diálogo.
291
Automatización y Workflows
2. Abierto el Depurar carta (el icono de Bicho en el lado derecho de la barra superior) y
escoger la Impresión Workflow opción. Esto generará un documento de PDF con un
graph de la campaña workflow, mostrando en un fondo rojo el workflow nodo elcur
documento de alquiler es en.
292
Capítulo 12
3. Otra vez en el Depurar carta, seleccionar el Editar Workflow opción. Esto navigate al
Workflow Vista de lista filtrada por el actual workflow. Clic en el workflow línea en la
lista para abrir e inspect su definición.
4. Workflows Tiene un Tercer modo de Vista, el esquema. Clicking En el Tercer tipo de Vista
icono, en el derecho superior después de la vista de forma, podemos ver el workflow
definición en un esquema.
El esquema también deja editar: doble click en los nodos para editar Actividades y
en las líneas para editar Transiciones.
293
Automatización y Workflows
Cómo trabaja...
El workflow las definiciones están almacenadas en el workflow modelo, y es también
reachable a través del Settings carta superior, y navigate a Técnico | Workflows
elemento de carta.
Su definición tiene Actividades. Los nodos o workflow estados, y Transiciones , definiendo
cuándo un workflow el estado actual tendría que mover a otro nodo.
Las transiciones a menudo dependen de un workflow Signal para ser provocados. Una
manera común de provocar un workflow la señal es a través de botones de forma. Los
botones apoyan un tipo="workflow" atributo para este.
Existiendo workflows es customizable: podemos editar o añadir actividades, y podemos
cambiar el
Transiciones connecting les. Sencillo customizations normalmente implica editar una
transición. En el workflow esquema, doble clicking una flecha de transición trae arriba de su
vista de forma. Allí nosotros rewire el workflow por modificar Actividad de Destino,
añadiendo Condición con una Pitón expressiencima para evaluar, o utilizando el grupo
Requirió para limitar la transición para ser provocada sólo por usuarios en un grupo de
seguridad seguro.
Ve también
f La documentación oficial proporciona más detalles sobre workflow definiciones:
https://www.odoo.com/documentation/9.0/reference/workflows.
html.
294
13
Servidor de
web
Desarrollo
Ent su capítulo, cubriremos los temas siguientes:
Introduction
Introduciremos el basics de la parte de servidor de la web de Odoo en este capítulo. Nota que
esto cubre las piezas fundamentales. Para funcionalidad de nivel alto, tendrías que referir a
Capítulo 14,
Desarrollo de Sitio web del CMS.
Todo de Odoo petición de web que maneja is conducido por la biblioteca de Pitón werkzeug
(http:// werkzeug.pocoo.org). Mientras la complejidad de werkzeug es
mayoritariamente escondido por Odoo conveniente wrappers, es un interesante leído para
ver cómo trabajo de cosas bajo el capote.
295
Desarrollo de Servidor de la web
Preparándose
Haremos uso de la biblioteca.Modelo de libro de Capítulo 4, Application Modelos, tan
en caso no has hecho tan todavía, grab su código para ser capaz de seguir los ejemplos.
Queremos dejar cualquier usuario a consulta la lista llena de libros. Además, queremos
proporcionar la misma información a programas vía un JSON petición.
La clase Principal(http.Controlador):
@Http.Ruta('/mi_módulo/reserva', tipo='http',
auth='ninguno') def libros(self):
Petición = de
registros.env['Biblioteca.Libro'].sudo().Búsqueda([])
resultado = '<html><mesa><de cuerpo><tr><td>'
Resultado += '</td></tr><tr><td>'.Une(
registros.mapped('Nombre'))
Resultado += '</td></tr></cuerpo></de
mesa></html>' resultado de regreso
Si consigues 404 errores al llegar a este punto, probablemente tienes más de una base de
datos disponible en vuestro caso. En este caso, es imposible para Odoo para determinar qué
base de datos está significada a serve la petición. Uso el --db-
filtra='^yourdatabasename$' parámetro para forzar que utiliza la base de datos exacta
instalaste el módulo en. Ahora el camino tendría que ser accesible.
Cómo trabaja…
Las dos partes cruciales aquí son que nuestro controlador está derivado de openerp .Http.
Controlador y que los métodos utilizamos para servir el contenido está decorado con
openerp. Http.Ruta. Heredando de openerp.Http.El controlador registra el
controlador con Odoo sistema de encaminamiento en una manera similar como modelos
está registrada, por heredar de openerp. Modelos.Modelo; también, el controlador
tiene un meta clase que cuida de este.
En general, los caminos manejaron por vuestro addon tendría que empezar con vuestro addon
nombre para evitar enfrentamientos de nombre. Naturalmente, si extiendes algunos addon
funcionalidad, utilizarás este addon nombre.
openerp.Http.Ruta
La ruta decorator nos dejo para decir Odoo que un método es para ser la web accesible en primer
lugar, y el primer parámetro determina en qué camino es accesible. En vez de una cuerda,
también puedes pasar una lista de cuerdas en caso utilizas la misma función para servir caminos
múltiples.
El argumento de tipo defaults a http y determina qué tipo de petición es para ser servido.
Mientras estrictamente hablando JSON es HTTP, declarando la segunda función cuando
tipo='json' vida de marcas mucho más fácil, porque Odoo entonces maneja
conversiones de tipo él.
No se preocupa sobre el auth parámetro por ahora, sea dirigido en la receta Restringe
acceso a web caminos accesibles en este capítulo.
Valores de regreso
Odoo tratamiento de las funciones' valores de regreso is determinó por el argumento de
tipo de la ruta decorator. Para escribe='http', normalmente queremos entregar algún
HTML, así que la primera función sencillamente regresa una cuerda que lo contiene. Una
alternativa es para utilizar petición.Marca_
Respuesta(), el cual da controlas encimat él encabezamientos para enviar la respuesta.
Tan, para indicar cuándo nuestra página estuvo actualizada último, podríamos cambiar la
última línea en libros() a:
Petición de regreso.Respuesta_de
marca( resultado, [
297
Desarrollo de Servidor de la web
('Último-modificado', email.utils.formatdate(
(
fields.Datetime.De_cuerda( petición.env['Biblioteca.Libro'].sudo()
En orden para la fragmento de preceder para trabajar, tendrás que añadir algunas
importaciones en la parte superior del file:
Importación de
email de la
importación
datetime
De openerp campos de importación
Para un JSON petición, sencillamente regresar la estructura de dato quieres entregar encima al
cliente; Odoo cuida de serialization. Para este para trabajar, te tendrías que restringir al dato
escribe aquello es
JSON serializable, Los cuales son aproximadamente diccionarios, lists, cuerdas, flotadores y
enteros.
298
Capítulo 13
openerp.Http.Petición
El objeto de petición es un objeto estático refiriendo a la petición actualmente manejada,
el cual contiene todo necesitas tomar acción útil. La mayoría de importante es el pro perty
petición. env, El cual contiene un Entorno objeta cuál es justo igual tan en
self.env Para modelos. Este entorno está atado al usuario actual, el cual es ninguno en
el ejemplo de preceder porque utilizamos auth='ninguno'. La carencia de una usuaria es
también por qué tenemos que sudo() todo nuestras llamadas a métodos de modelo en el
código de ejemplo.
Si estás utilizado a desarrollo de web, esperarás la sesión que maneja, el cual es
perfectamente correcto. Petición de uso.Sesión para un OpenERPSession objeto (cuál es
bastante un delgado wrapper
Alrededor del Sessiencima objeto de werkzeug ), y petición.Sesión.sid Para acceder
la sesión ID. Para almacenar valores de sesión, justo tratar petición.Sesión como
diccionario:
Petición.Sesión['hola'] = 'mundo'
petición.Sesión.Consigue('hola')
Allí ha más…
La ruta decorator puede tener algunos parámetros extras para personalizar su
comportamiento más allá. Por default, todos métodos de HTTP están dejados, y Odoo
intermingles los parámetros pasaron. Utilizando los métodos de parámetro, puedes
pasar una lista de métodos para aceptar, el cual normalmente sería uno de cualquier
['CONSEGUIR'] o ['CORREO'] .
Para dejar peticiones de origen de la cruz (bloque de navegadores AJAX y algunos otros tipos
de peticiones a ámbitos otro que donde el guión estuvo cargado de para seguridad y razones
de intimidad), puestos el cors parámetro a * para dejar peticiones de todos los
orígenes, o algunos URI para restringir peticiones a unos originando de este URI. Si este
parámetro es unset, el cual es el default, el Acceso-Control-Dejar-encabezamiento
de Origen no es puesto, dejando tú con el browser comportamiento estándar. En nuestro
ejemplo, podríamos querer puestos lo encima /mis_libros/de módulo/json para
dejar los guiones estiraron de otros sitios web que acceden la lista de libros.
Por default, Odoo protege tipos seguros de peticiones de un ataque sabido cuando
cruz-site petición forgery por pasar un token a lo largo de en cada petición. Si quieres
apagar aquello, puesto el parámetro csrf a Falso , pero nota que esto es una idea
mala en general.
299
Desarrollo de Servidor de la web
Ve también
Si te múltiplo anfitrión Odoo databases en el mismo caso y cada base de datos tiene web
diferente caminos accesibles encima posiblemente nombres de ámbito múltiple por base de
datos, las expresiones regulares estándares en el --db-parámetro de filtro no podría
ser bastante para forzar la base de datos correcta para cada ámbito. En aquel caso, uso el
módulo comunitario dbfilter_de_encabezamiento de https://github.com/oca/server-
tools para configurar los filtros de base de datos en el proxy nivel.
Para ver cómo utilizando las plantillas hace modularity posibles, ver la receta Modifica
un existiendo handler más tarde en el capítulo.
Preparándose
Cuando extendemos código de la receta anterior, también dependeremos de la
biblioteca.Modelo de libro de Capítulo 4, Modelos de Aplicación, así que tendrías que
conseguir su código para proceder.
registros.mapped('Nombre'))
Resultado += '</td></tr></cuerpo></de
mesa></html>' resultado de regreso
2. Añadir un camino que espectáculos todos los libros e indica cuál estuvo escrito por
el usuario actual, si cualquiera:
@Http.Ruta('/mi_módulo/todo-marca/de libros-
mina', tipo='http', auth='público')
def Toda_mina_de marca_de los libros(self):
Petición = de
registros.env['Biblioteca.Libro'].sudo().Búsqueda([])
300
Capítulo 13
Resultado = '<html><mesa><de
cuerpo>' para récord en
registros:
Resultado += '<tr>'
Si récord.Autor_ids & request.env.Usuario.Socio_id:
resultado += '<th>'
Más:
Resultado +=
'<td>' resultado +=
record.name
Si récord.Autor_ids &
petición.env.Usuario.Socio_id: resultado +=
'</th>'
Más:
Resultado +=
'</td>' resultado +=
'</tr>'
Resultado += '</cuerpo></de
mesa></html>' resultado de regreso
Cómo trabaja…
La diferencia entre métodos de autentificación es básicamente qué puedes esperar del
contenido de petición.env.Usuario .
Para auth='ninguno', el registro de usuario es siempre vacío, incluso si un usuario
autenticado es accessing el camino. Uso esto si quieres servir contenido que tiene ninguna
dependencia en usuarios, o si quieres proporcionar base de datos funcionalidad agnóstica
en un servidor módulo ancho.
301
Desarrollo de Servidor de la web
Allí ha más…
La magia para métodos de autentificación pasa en el ir.Modelo de http de la base
addon. Para cualquier valor pasas al auth parámetro en vuestra ruta, Odoo busca una
función llamó _auth_método_<yourvalue> en este modelo, así que puedes fácilmente
customize esto por heredar este modelo y declarando un método que cuida de vuestro
método de autentificación de elección.
Cuando un ejemplo, proporcionamos un grupo de base de método_de
autentificación_usuario qué aplica un actualmente logged en usuario quién es un
miembro del grupo con XML ID base.Usuario_de grupo:
De openerp excepciones de importación, http,
modelos de openerp.Petición de importación
del http
Clase
IrHttp(modelos.Modelo):
_hereda = 'ir.Http'
302
Capítulo 13
'biblioteca.Libro'):libro>", tipo='http',
auth='ninguno')
Cómo trabaja…
Por default, Odoo (de hecho werkzeug) intermingles con CONSEGUIR y parámetros de
CORREO y les pasa tan argumento de palabra clave a vuestro handler. Tan por
sencillamente declarando vuestra función cuando esperando un parámetro libro
llamado_id, introduces este parámetro tan tampoco CONSEGUIR (el parámetro en el
URL) o CORREO (normalmente pasó de largo formas con vuestro handler cuando acción)
parámetro. Dado que no añadimos un default valor para este parámetro, el runtime
levantará un error si intentas acceder este camino sin poner el parámetro.
Las segundas marcas de ejemplo uso del hecho that en un werkzeug entorno, más los
caminos son virtuales en todo caso. Así que sencillamente podemos definir nuestro camino
cuando conteniendo alguna entrada. En este caso, decimos que esperamos el ID de una
biblioteca.Libro como el último componente del camino. El nombre después del colon es el
nombre de un keyword argumento. Nuestra función se apellidará, con este parámetro pasó tan
argumento de palabra clave. Aquí, Odoo cuida de mirar arriba de este ID y entregando un
explorar récord, el cual naturalmente trabajos únicos si el usuario que accede este camino tiene
permisos apropiados. Given que el libro es un explorar récord, sencillamente podemos
reciclar la función del primer ejemplo por pasar book.id tan libro de parámetro_id para dar
fuera del mismo contenido.
303
Desarrollo de Servidor de la web
Allí ha más…
Definiendo los parámetros dentro del camino es un functionality entregó por werkzeug, el
cual se apellida convertidores. El convertidor de modelo está añadido por Odoo, el cual
también define los modelos de convertidor, aquello acepta una coma lista separada de
IDs y pasa un conjunto récord que contiene aquellos IDs a vuestro handler.
La belleza de convertidores es que el runtime coacciona los parámetros al tipo esperado,
mientras eres por tu cuenta con parámetros de palabra clave normal. Estos están entregados
como cuerdas, y tienes que cuidar de las conversiones de tipo necesarias tú, cuando vistos enel
abeto st ejemplo.
Construido-en werkzeug los convertidores incluyen int, flotador, y cuerda , pero también
más intrincado unos como camino, cualquiera, o uuid . Puedes mirar arriba de su
semantics en http://werkzeug.
pocoo.org/docs/0.11/routing/#builtin-Convertidores.
Ve también
Odoo los convertidores hechos de encargo están definidos en ir_http.py en el módulo
de base y registrado en el _conseguir_método de convertidores de ir.Http . Cuando un
ejercicio, puedes crear vuestro convertidor propio que te dejas para visitar el
/mi_libro/de módulo_detalla/Odoo+página de recetario para recibir los detalles
de este libro (si lo añadiste a vuestra biblioteca antes). La implementación de este
convertidor esi ncluded en el código de ejemplo para esta receta.
Preparándose
Instalar el módulo de sitio web e inspeccionar el sitio web /de camino/info. Ahora oficio
un módulo nuevo que depende de sitio web y utiliza el código siguiente.
304
Capítulo 13
<xpath expr="//dl[@t-
foreach='Aplicaciones']" la
posición="reemplaza">
<Mesa de clase="de la mesa">
<tr t-foreach="Aplicaciones" t-
tan="aplicación"> <th>
<Un t-att-
href="aplicación.Sitio web">
<t t-esc="app.name" /></un>
</th>
<td><t t-esc="Aplicación.Resumen"
/></td> </tr>
</Mesa>
</xpath>
</tempTarde>
</odoo>
Ahora, cuándo visitando el info página, sólo veremos una lista filtrada de aplicaciones
instaladas, y en una mesa como opposed al original lista de definición.
Cómo trabaja
En el primer paso, nosotros override un existiendo QWeb plantilla. Para descubrir cuál
aquello es, tendrás que consultar el código del original handler. Normalmente, acabe con
la línea de orden siguiente, el cual te dices que necesitas a override template.name:
Petición de regreso.render('template.name', valores)
En nuestro caso, el handler utiliza una plantilla llamó website.info, pero esto uno es
inmediatamente extendido por otra plantilla sitio web llamado.Sitio web_de
espectáculo_info, así que es más conveniente a override este un. Aquí,
reemplazamos la lista de definición que muestra aplicaciones instaladas con una mesa.
Para detalles aproximadamente qué QWeb trabajos de herencia, consulta Capítulo 14,
Desarrollo de Sitio web del CMS.
305
Desarrollo de Servidor de la web
Para override el handler método, tenemos que identificar la clase que define el handler,
Cuál es openerp.addons.Sitio web.Controladores.Principal.Sitio web, en
este caso. Importamos la clase para ser capaz de heredar de él. Ahora nosotros override el
método y cambiar el dato pasó a la respuesta. Nota que lo que el overridden handler los
regresos es un objeto de Respuesta y no una cuerda de HTML, cuando las
recetas anteriores hicieron por el bien de brevity. Este objeto
contiene una referencia a la plantilla para ser utilizada y los
valores accesibles al templato, pero es sólo evaluado en el muy fin de la petición.
Allí ha más…
Cuando visto en la sección de preceder, la herencia con controladoras trabaja
ligeramente de manera diferente que herencia de modelo: de hecho necesitas una
referencia a la clase de base y para utilizar herencia de Pitón encima lo.
No olvida para decorar vuestro nuevo handler con el @http.Ruta decorator; Odoo utiliza él
como marcador for cuál los métodos están expuestos a la capa de red. Si omites el decorator,
de hecho haces el handler el camino inaccesible.
El @http.Ruta decorator él behaves de modo parecido a campo declarations: cada valor
tú no puesto será derivado del decorator de la función eres primordial, así que no tenemos
que repetir valores no queremos cambio.
Después de recibir un objeto de respuesta de la función tú override, puedes hacer mucho
más de justo cambiando el QWeb contexto:
f Puedes añadir o sacar HTTP encabezamientos por manipular
respuesta.Encabezamientos.
f Si quieres render una plantilla enteramente diferente, puedes poner
respuesta.Plantilla.
f Para detectar si una respuesta está basada en QWeb en primer lugar, consulta
response.is_qweb.
f El código de HTML resultante es available por llamar respuesta.render().
306
Capítulo 13
Ve también
f Detalles de QWeb las plantillas serán explicadas en Capítulo 14, desarrollo de Sitio web
del CMS.
db = 'odoo9'
usuario = 'admin'
password = 'admin'
uid = xmlrpclib.ServerProxy( 'Http://localhost:8069/xmlrpc/2/común')\
db = 'odoo9'
usuario =
'admin'
307
Desarrollo de Servidor de la web
Contraseña = 'admin'
'params': {
'db': db,
'login':
usuario,
'Contraseña': contraseña,
},
}),
{'Contenido-escribe':
'aplicación/json'}) resultado =
urllib2.urlopen(Petición).Leído() resultado
= json.Cargas(resultado)
Sesión_id = resultado[ essult'][
esession_id'] petición = urllib2.Petición(
'Http://localhost:8069/web/dataset/llamada_k
w', json.Vertederos({
'jsonrpc': '2.0',
'params': {
Soyodel': 'ir.Módulo.Módulo',
soyethod': esearch_lee',
'args': [
[( Estate', '=',
'instalado')], ['nombre'],
],
'kwargs': {'Contexto': {'lang': 'fr_FR'}},
},
}),
{
'X-Openerp-Sesión-Id': sesión_id,
'Contenido-escribe':
'aplicación/json',
})
Resultado =
urllib2.urloBolígrafo(petición).Leído()
resultado = json.Cargas(resultado)
Para módulo en resultado[
essult']: módulo de
impresión['nombre']
Ambas fragmento de código imprimirán una lista de módulos instalados, y porque pasan un
contexto que conjuntos la lengua a francés, la lista será en francés si hay traducciones
disponibles.
308
Capítulo 13
Cómo trabaja…
Ambas fragmento llaman la búsqueda de función_leída, el cual es muy conveniente
porque puedes especificar un ámbito de búsqueda en el modelo llamas, pase una lista de
campos quieres ser returned, y recibir el resultado en uno pide. En versiones más viejas
de Odoo, tuviste que llamar búsqueda primero para recibir una lista de IDs y entonces
llamar leído a de hecho leído el dato.
La búsqueda_leída regresa una lista de diccionarios, con las llaves siendo los
nombres del fields pedidos y los valores el dato del registro. El ID campo siempre será
transmitido,
Ningún asunto si lo pediste o no.
XMLRPC
El XMLRPC API espera un usuario ID y una contraseña para cada call, el cual es por qué
nosotros necesita a fetch este ID vía el método autentica en el camino
/xmlrpc/2/común. Si ya sabes el usuario ID, puedes skip este paso.
Apenas sabes el usuario ID, puedes llamar el método de cualquier modelo por llamar
ejecuta_kw en el camino /xmlrpc/2/objeto. Este método espera la base de datos
quieres ejecutar la función encima, el usuario ID y contraseña para autentificación, entonces
el modelo quieres llamar vuestra función encima, y entonces el nombre de la función. El
próximos dos parámetros obligatorios are una lista de argumentos posicionales a vuestra
función, y un diccionario de argumentos de palabra clave.
JSONRPC
No es distraído por la medida del ejemplo de código; aquello es porque la pitón no ha
construido en soporte para JSONRPC. Apenas has envuelto el urllib calls en algún
helper funciones, el ejemplo será tan conciso como el XMLRPC un.
Cuando JSONRPC es stateful, la primera cosa tenemos que hacer es para pedir una
sesión en /sesión/ de web/autentica. Esta función toma la base de datos, el
nombre del usuario, y
Su pasespada.
La parte crucial aquí es que grabamos la sesión ID Odoo creado, el cual pasamos en el
encabezamiento X-Openerp-Sesión-Id a /web/dataset/llamada_kw . Entonces la
función behaves igual cuando ejecuta_kw de; necesitamos pasar un nombre de modelo y
una función a call encima lo, entonces posicional y argumentos de palabra clave.
Allí ha más…
Ambos protocolos te dejan para llamar básicamente cualquier función de vuestros modelos.
En caso no quieres una función para ser disponible vía cualquier interfaz, prepend su
nombre con un underscore – Odoo ganado't expone aquellos funciona tan RPC llamadas.
309
Desarrollo de Servidor de la web
Además, necesitas cuidar que vuestros parámetros, así como los valores de regreso, es
serializable para el protocolo. Para ser seguro, te restringe a valores escalares, dictionaries, y
listas.
Cuando puedes hacer aproximadamente igual con ambos protocolos, es hasta ti cuál para
utilizar. Esta decisión tendría que ser principalmente conducida por qué vuestros soportes de
plataforma más. En un contexto de web, eres generalmente mejor fuera con JSON, porque
Odoo deja JHIJO handlers para pasar un CORS encabezamiento oportunamente (ve la Marca
un camino accesible de la receta de red de este capítulo para detalles). Esto es bastante
difícil con XMLRPC.
Ve también
Los métodos empresariales más interesantes para llamar en los modelos están explicados
en Capítulo 5,
Lado de Servidor básico Lógica Empresarial.
310
14
Sitio web de
CMS
Desarrollo
En este capítulo, cubriremos los temas siguientes:
Introducción
Odoo Viene con un CMS plenamente presentado el sistema implementado por el sitio web
addon. Algunos funcionalidad de nivel bajo está proporcionada por la web addon, así que si
necesitas mirar arriba código, mantener ambos módulos en mente.
Preparándose
Crear un módulo vacío nombró ch13_r01 e instalar él en vuestra base de datos de prueba.
Marca seguro estemo dule depende de el módulo de sitio web, cuando utilizamos algunos
de su funcionalidad.
311
Desarrollo de Sitio web del CMS
Después de actualizar vuestro module, tendrías que ver que Odoo los sitios web tienen un
fondo amarillo y un un poco molesto Hola mundial popup en cada carga de página.
312
Capítulo 14
Cómo trabaja...
En la base de Odoo mentiras de CMS un XML templating el motor llamó QWeb, el cual es
discoussed en detalle en la receta siguiente. Por ahora, es bastante para saber que lo
podemos utilizar para inyectar nodos a existir documentos. En el ejemplo, cambiamos el
sitio web de vista.Ventajas_frontend para enlazar a nuestro CSS y archivos de
Javascript. Esta vista será estiradat o construye todo el HTML para el sitio web, así que
puedes ser seguro vuestro código es disponible encima todas las páginas.
Cuando podemos ser seguro el sitio web de vista.Ventajas_frontend está
estirado dentro de un nodo de cabeza del HTML, sencillamente podemos añadir los
archivos necesitamos y posiblemente ajustar o añadir otro nodes en el elemento de
cabeza también.
Para CSS archivos, asuntos de orden. Tan si necesitas a override un estilo definido en otro
addon, tendrás que cuidar que vuestro archivo está cargado después del archivo original
quieres modificar. Esto puede ser hecho por cualquier ajustando el campo de prioridad de
vuestra vista o directamente heredando del addon vista que inyecta la referencia al CSS.
Para detalles, consultar el Capítulo 8, Backend Vistas, la receta que Cambia existiendo
vistas: herencia de Vista.
Para evitar ordenando asuntos con Javascript, Odoo utiliza un mecanismo muy similar a
RequireJS (http://requirejs.org): En vuestro archivo de Javascript, llamas
odoo.Define(), el cual recibe el namespace quieres definir como el primer argumento, y
una función que contiene la implementación real como el segundo argumento.
El nombre para ser definido tendría que ser vuestro addon nombre. En caso exportas
muchas partes lógicamente diferentes de funcionalidad, definirles en funciones diferentes,
con vuestro addon nombre prepended y separado by puntos para evitar que nombran
conflictos en el futuro. Esto es lo que el módulo de web , el cual define, entre otros,
web.Núcleo y web.Dato . La función de definición recibe sólo un parámetro, requiere,
el cual es una función puedes utilizar para obtener referencias a JavaGuión namespaces
definió en otros módulos o en el núcleo. Uso esto para todas las interacciones con Odoo y
nunca confiar en el global odoo objeto.
Vuestra función propia entonces puede regresar un objeto que señala a las referencias quieres
hacer disponible para otro addons, o nada si hay no tales referencias. Ser lavish con exportador
vuestros objetos propios; pocas cosas son más frustrando que teniendo que saltar a través de
hoops para utilizar algunos existiendo funcionalidad justo porque su desarrollador no molestó
para exportarlo properly. El objeto regresas aquí es lo que otro código consigue cuándo él llama
requerir('yourmodule').
Por convención, vuestros archivos se tendrían que apellidar como vuestro módulo con la
extensión apropiada añadida y vivir en estático/src/css o estático/src/js respectivamente.
Único if vuestros archivos devienen bastante grandes para ser un asunto de mantenimiento tiene
que les partiste arriba a más pequeño chunks.
El requerir el mecanismo hablado aquí es nuevo para Odoo 9.0. En versiones más viejas,
addons tratando necesidad de Javascript para definir una función con el mismo name
cuando el addon en el openerp namespace. Esta función recibe una referencia al caso
actualmente cargado como parámetro, de qué API las funciones son para ser accedidos.
Tan, para upgrade existiendo código, cambio esto a un odoo.Define cláusula e importar los
objetos necesarios vía requerir.
313
Desarrollo de Sitio web del CMS
Allí ha más...
En vez de pasar sencillo CSS a Odoo, puedes también uso de marca de menos
(http://lesscss.org), el cual es una notación de nivel más alta para CSS aquello ayuda
escribes más eficaz CSS código. Ciertamente para bases de código grande, mejore maintainability
mucho. Dado Odoo utiliza esto internamente en todo caso, puedes confiar encima lo siendo
disponible. Tan, para utilizar menos en vez de sencillo CSS, punto justo al menos file en vuestro
elemento de enlace y texto de tipo="del uso/menos" – esto hará Odoo carrera lessc en
vuestro archivo para generar CSS en la mosca sin ti teniendo que hacer cualquier cosa para él.
Preparándose
Cuando hacemos uso de la biblioteca.Modelo de libro, consigue capítulo 4 código
para mi_módulo. Para comodidad, el código de esta receta contiene una copia de él.
314
Capítulo 14
<ul
Clase="col-md-10">
<li t-foreach="Libro.Autor_ids" t-
tan="autor" itemprop="autor">
<t t-esc="author.name" />
</li>
</ul>
</Artículo>
</t>
<Sección contenteditable="Falso">
Esto es un texto no editable después del list de
libros. </Sección>
</t>
</Plantilla>
</odoo>
'ch13_r02.Libros',
{
'Libros':
petición.env['Biblioteca.Libro'].Búsqueda([]),
})
Con este código en sitio, los usuarios pueden consulta existiendo libros y ver sus
detalles. Permisos apropiados dados, los usuarios también serán ofrecidos para
cambiar detalles de libro y un par de otros textos.
Cómo trabaja...
Primero, creamos una plantilla llamó libros que suele generar el HTML necesario de
mostrar una lista de libros. Todo del código está envuelto en un t elemento con el t-conjunto
de atributo de la llamada, el cual hace Odoo render el sitio web.Plantilla de diseño e insertar
nuestro contienda en el sitio la plantilla llamada ha designado para él. De este modo,
conseguimos un llenos Odoo página web con la carta, footer, y tan encima, sin teniendo que
repetir cualquier código. Si dejas fuera de esta llamada, tendrás que generar esto o código
similar tú.
315
Desarrollo de Sitio web del CMS
Bucles
Para laborable oficialmente conjuntos, necesitas un construir a bucle a través de listas.
Tiene una mirada en el interior del t-elemento de llamada, donde la generación de
contenido real pasa. La plantilla espera ser rendered ingenioh un contexto que tiene una
variable llamó los libros puestos e itera a través de él en el t-foreach elemento. La
iteración puede pasar en un t elemento, en qué caso sus contenidos están repetidos para
cada miembro del iterable aquello estuvo pasado en el t-foreach atributo. También
puedes colocar un t-foreach y t-tan atributo en algún elemento arbitrario; entonces este
elemento y sus contenidos serán repetidos para cada elemento en el iterable. El t-tan el
atributo es obligatorio y será utilizado como el nombre del iterator variable para utilizar
paraun ccessing el dato iterado. Rato el uso más común para esta construcción es para iterar
sobre conjuntos récord, lo puedes utilizar encima cualquier Pitón objeta aquello es iterable.
Atributos
Utilizamos tan muchos del HTML semántico5 elementos como posibles, el cual es por qué el
actual el dato está envuelto en una etiqueta de artículo. Para máquina readability, algunas
propiedades* de elemento están sujetadas.
Puedes leer más aproximadamente esto en esta receta es Ve también sección.
Ahora foco en el t-attf-atributo de clase aquí. Esto será evaluado por QWeb para ser el
attribute la clase con los contenidos evaluó como cuerda de formato. Aquello es, el libro
de fila de la cuerda- está pasado cuando es y los contenidos del #{...} La
fragmento está evaluada tan código de Pitón. Esto es diferente de t-att-dateCreated (nota el
desaparecido 'f', el primero es un unttribute cuerda de formato, el último una evaluación)
utilizó abajo, donde el contenido entero está evaluado tan código de Pitón. Ambos forma
justo pasar la parte de su nombre después de la segunda pizca como el nombre del atributo
para ser construido.
Es más o menos hasta you cuándo para escoger un t-attf-* construcción y cuándo para
utilizar t-att-*, la regla de pulgar es para utilizar una cuerda de formato si el resultado
contiene mucha cuerda literals en todo caso y una evaluación otherwise.
Campos
El h2 y div etiquetas que sigue uso el t-campo attribute. Estas necesidades de atributo para ser
pasados un campo dentro de un conjunto récord con longitud un y limpiamente deja el usuario
para cambiar el contenido mostrado cuándo el sitio web es edita el modo está activado.
Naturalmente, esto es subject a un control de permiso y sólo dejared si el usuario actual tiene
escribir permisos en el registro mostrado. Con un opcional t-campo-atributo de opciones,
puedes dar un diccionario de opciones para ser
Pasado al campo renderer, incluyendo el widget para ser utilizado. Actualmente, hay no
cantidad vasta of widgets para el backend, así que las elecciones son un poco limitadas aquí.
Conditionals
Nota que la división que muestra la fecha de publicación está envuelta por un t elemento
con el t-si conjunto de atributo. Este atributo está evaluado tan código de Pitón y el
elemento sólo rendered si el resultado es truthy . En el ejemplo, sólo muestramos el div
clase si hay de hecho un conjunto de fecha de la publicación.
316
Capítulo 14
Nota que t-si no convive bien con otro templating atributos como
t-esc o t-campo en el mismo elemento. Puesto cada cual de ellos en
su elemento propio, porque, otherwise, el t-si normalmente gana y
los otros atributos no son evaluados más.
Inline Editando
Los cambios hicieron por un usuario tampoco será propagado al registro de base de datos
conectado si el cambio pasado dentro de un t-nodo de campo, o a la vista en cuestión si es
algunos otro nodo marcado como editable. A Nodos de contenido les gustan elementos de
sección no necesita para ser marcado como editable, son editables por default. Para girar un
elemento editable leído-único, uso el atributo
contenteditable=Falso.
Nota que editando una vista vía la editora de sitio web pone el
noupdate bandera en esta vista. Esto significa que cambios de código
subsiguiente nunca harán él a la base de datos de vuestro cliente. Para
también conseguir la facilidad de uso de inline editando y la posibilidad
de actualizar vuestro código de HTML en liberaciones subsiguientes,
crea uno ve aquello contiene los elementos de HTML semánticos y un
segundo un aquello inyecta elementos editables. Entonces sólo la vista
última será noupdate y todavía puedes cambiar el anterior.
Para el CSS las clases utilizaron aquí, consulta bootstrap documentación, cuando
enlazado en esta receta es Ve también sección.
El controlador en paso 2 justo renders la plantilla, complacer referir al Capítulo 13,
Desarrollo de Servidor de la Web, la receta Modifica un existiendo handler para detalles.
Allí ha más...
Dado la manera t-elementos de llamada están evaluados, puedes utilizar t-poner
elementos para pasar información a la plantilla llamas. Esto puede ser muy útil si tienes
algunos generalizaron a plantillas les gusta el sitio web.Diseño o informe.Externo_pone
fuera, los cuales muestran dato quieres ver casi siempre. Les adapta no para imprimir
elementos seguros si alguna variable está puesta y puesto él vía un t-elemento puesto en
la página o informe donde quieres suprimir el elemento en cuestión. Estas ayudas para
evitar mucho code duplicación.
317
Desarrollo de Sitio web del CMS
Dentro de t-foreach bucles, tienes acceso a un par de variables cuyos nombres están derivados
del acompañantes t-tan atributo. Cuando es libro en el ejemplo encima, tenemos acceso al
variparidad de libro_capaz qué contiene el valor incluso para incluso índices mientras
iterando y extraños para extraños unos. En este ejemplo, utilizamos esto para ser capaz de tener
colores de fondo alternos en nuestra lista. Otras variables interesantes en este caso serían
índice_de libro, which regresa la corriente (cero-basado) índice en la iteración,
libro_primero y libro_último, los cuales son
Cierto si esto es el primer o última iteración respectivamente, y valor_de libro, el cual
contendría el valor del elemento si la variable de libro iteramos encima eraun di ctionary; en
este caso, el libro iteraría a través de las llaves del diccionario.
El elemento de plantilla es una taquigrafía para un elemento récord que conjuntos algunas
propiedades en el registro para ti. Mientras allí ha nunca una razón no para utilizar la
comodidad de la plantilla element, tendrías que saber qué pasa bajo el capote: el elemento
crea un registro del modelo ir.ui.Vista con tipo qweb. Entonces, dependiendo de el nombre
del elemento de plantilla y heredar_id atributos, el heredar_id el campo en el registro
de vista será puesto. En caso tél la plantilla tiene el atributo conjunto primario a Cierto , el
campo de modo delregistro de vista será puesto a primario . Finalmente, un
campo de arco es crafted con el elemento de raíz correcto (t para vistas de no heredar,
dato para heredar vistas) y un t-atributo de nombre está puesto for vistas primarias.
Mantiene en importar que QWeb es un perfectamente genérico templating motor, así que
siempre que necesitas generar contenido en un Odoo contexto, uso un Qweb vista que te
render por llamar
env['ir.ui.Vista'].render('xmlid', parámetros). Especialmente para
generating XML documentos, esto es conveniente, pero puedes generar cada otra clase
de texto también.
Ve también
Para un más en-discusión de profundidad de controladores, ver el Capítulo 13, Desarrollo de
Servidor de la Web, las recetas Hacen un camino accesible de la red y Restringir unccess a web
caminos accesibles.
Para detalles encima herencia de vista, ver el Capítulo 8, Backend Vistas, la receta que
Cambia existiendo vistas: herencia de Vista.
318
Capítulo 14
Preparándose
Cuando hacemos uso de la biblioteca.Modelo de libro, consigue capítulo 4 código
para mi_módulo. Para comodidad, el código de esta receta contiene una copia de
él.
319
Desarrollo de Sitio web del
CMS
3. Añade opciones:
<xpath expr="//div[@id= nippet_opciones']" interior="de
posición">
<div Dato-selector=".Mascota_de tijeretazodel libro"
Dato-gota-cercano="p, h1, h2, h3, blockquote, .Bien,
.Dato" de tablero-gota-en=".Contenido">
<li Clase="dropdown-submenu">
<un href="#">el espectáculo
reserva</un> <ul
clase="dropdown-carta">
<li Dato-seleccionar_fragmento="de libro_de
la clase-espectáculo3"> <un>3</un>
</li>
<li Dato-seleccionar_fragmento="de libro_de
la clase-espectáculo5"> <un>5</un>
</li>
<li Dato-seleccionar_libro="de
clase_snippetshow10"> <un>10</un>
</li>
<li Dato-seleccionar_libro="de
clase_snippetshow15"> <un>15</un>
</li>
</ul>
</li>
</div>
<div Dato-selector=".Mesa_de fragmento
del libro"> <li clase="dropdown-
submenu">
<Un href="#">estilo de
Mesa</un> <ul
clase="dropdown-carta">
<li Dato-toggle_mesa="de clase-tachó">
<un>Tachado</un></li>
<li Dato-toggle_clase="tablebordered">
<un>Bordered</un></li>
<li Dato-toggle_clase="tablecondensed">
<un>Condensado</un>
</li>
</ul>
</li>
</div>
</xpath>
320
Capítulo 14
.Anexa(
jQuery('<td />').Texto(book.name),
jQuery('<td />').Texto(
Libro.Liberación_de
fecha)
)
321
Sitio web de CMS Development
);
})
});
},
});
});
Después de actualizar vuestro módulo, estás ofrecido una fragmento llamó libros más
Tardíos, el cual muestra un configurable cantidad de libros en una lista, ordenado por
su fecha de publicación.
Cómo trabaja...
Inyectas vuestra fragmento directamente a la vista de la barra de fragmento. Qué es
crucial es que sujetas las clases correctas e insertar vuestro código en el sitio correcto.
Unas necesidades de fragmento para tener uno arraiga elemento (en nuestro caso, el outermost
div) aquello contiene un elemento con la clase oe_fragmento_thumbnail unnd otro con clase
oe_cuerpo_de fragmento.
El primero suele exhibición la fragmento en la barra, el segundo contiene la definición real
de la fragmento. Para el thumbnail, hace sentido para utilizar un fontawesome icono y
añadir algunas clases para el diseño. Para el cuerpo de fragmento, puedes añadir cualquier
HTML te necesidad para vuestros objetivos. En general, es una idea buena de utilizar
elementos de sección y el bootstrap clases, porque, para ellos, Odoo ofertas de editor
editan y resize controles fuera de la caja.
La posición para insertar el snippet determina en qué sección de la barra aparece. Nuestro
La elección era //div[@id=
nippet_característica']/div[@clase='o_cuerpo_de tablero'], el cual coloca
él en la sección de características. Con el IDs estructura_de fragmento, contenido_de
fragmento, y efecto_de fragmento , puedes colocar ynuestra fragmento en el respectivo
otras secciones.
El div inyectamos en //div[@id= nippet_opciones'] ofrece las elecciones de usuario
en el personalizar carta. Nota el dato de atributo-selector que contiene un JQuery el selector
que determina para qué elemento la opción est o ser mostrado. En el ejemplo, la primera
lista de opción está mostrada cuándo el contenedor entero está seleccionado, mientras el
segundo un, sobre el estilo de mesa, está mostrado cuándo la mesa está seleccionada.
El dato de atributos-gota-cercano y dato-gota-en determinar donde la fragmento cun ser
colocado cuándo arrastrando él fuera de la barra de fragmento. Aquellos son también JQuery
selectors y, en el ejemplo, dejamos poner la fragmento básicamente anywhere aquel
contenido puede ir.
Para las opciones ellos, el dato de atributos-seleccionar_clase y dato-toggle_cl el asno
deja el usuario para poner cualquier un (selecciona) o múltiplo (toggle) clases en el
elemento seleccionado por el dato-atributo de selector. Nuestro primer conjunto de
opciones pone las clases más tarde utilizadas por el código de Javascript. El segundo
conjunto de opciones pone clases directamente ent someta, el cual cambiará su diseño
consiguientemente.
El código de Javascript utiliza el marco de animación de la fragmento para ejecutar algún código
cada vez la fragmento está cargada. Lo utilizamos a consulta la lista actual de libros para ser
presentados al usuario.
322
Chapter 14
Allí ha más...
Después de completar esta receta, sabes bastante para crear Odoo temas. Un addon está
considerado un tema si contiene archivos de dato único, CSS y código de Javascript. Uso QWeb
vistas y fragmento para adaptar el código de HTML del sitio web como necessary y CSS para
styling. Para el addon para ser reconocido como tal en la tienda de aplicación, el addon es
manifiesta tiene que poner la llave de aplicación a Cierto y utilizar una subcategoría de tema,
cuando encontrado en https://www.odoo.com/apps/temas.
323
15
Cliente de
web
Desarrollo
En este capítulo, cubriremos los temas siguientes:
f Creando hecho de encargo
f
widgets
Utilizando lado de cliente QWeb
f
las plantillas que Hacen RPC
f
f
llamadas als erver pruebas de
Escritura para código de lado del
cliente que Depura vuestro código
de lado del cliente
Introducción
Odoo cliente de web, o backend, es el sitio donde los empleados gastan la mayoría de su
tiempo. En Capítulo 8, Backend Vistas, has visto cómo para utilizar las posibilidades de
existir el backend ofertas. Aquí, tendremos una mirada en cómo para extender y
personalizar aquellas posibilidades. Todo del código siguiente dependerá de el módulo de
web. Nota que en el tiempo de escribir, allí existir dos versiones del módulo de web para
Odoo 9.0: el community versión y la versión de empresa, los cuales son bastante diferentes
de cada otro, incluso aunque comparten el mismo nombre. Nosotros sólo charla sobre la
versión comunitaria aquí.
Creando hecho de encargo widgets
Cuando has visto en Capítulo 8, Backend Vistas, hay un plethora de widgets que exhibición
vuestro dato en una manera segura. Para demostrar cómo para crear vuestro propio widget,
escribiremos uno aquello deja el usuario escoge un mucha2una referencia de un
predefined selección de valores en la forma de una lista de botones. El resultado mira
tanmewhat similar al muchos2muchos_checkboxes widget, pero con botones en vez de
checkboxes.
325
Desarrollo de Cliente de la web
Preparándose
Necesitarás crear un vacío addon aquello depende de el módulo de web; lo llamamos
ch15_r01 aquí.
326
Capítulo 15
'Dato-id': id,
'Clase': 'btn btn-default btn-sm',
})
.Texto(description.name)
);
});
Esto.Eficaz_readonly_cambiado();
Regreso esto._super.Aplica(esto, argumentos);
},
.attr('Dato-id'))
);
}, eficaz_readonly_cambiado()
{
327
Desarrollo de Cliente de
la web
Esto.$el.Encuentra('botón').
prop('disabled',
esto.Consigue('eficaz_readonly'));
},
});
13. Finalmente, marca la forma de socio utiliza nuestro widget para escoger la persona
de ventas:
<?xml Versión="1.0" codificando="UTF-
8"?> <openerp>
<Dato>
<Récord id="modelo_de forma_de socio" de
vista="ir.ui.Modelo"> <de nombre de campo="de
vista">res.Socio</field>
<Nombre de campo="hereda_id" ref="base.Forma_de
socio_de la vista"
/>
<Tipo de arco="de nombre" de campo="xml">
<Usuario de nombre="del campo_id" atributos="de
posición">
328
Capítulo 15
<Nombre de atributo="widget">
muchos2un_botones</atributo>
</Campo>
</Campo>
</Récord>
</Dato>
</openerp>
Cuándo abres una forma de socio después de instalar el módulo, verás dos botones en el
campo de persona de las ventas que te dejas para seleccionar un usuario. El botón del usuario
actualmente seleccionado está destacado.
Cómo trabaja...
La primera elección cuándo developing un widget es para escoger la clase de base correcta.
La clase de base fundamental para widgets es Widget (definido por web.widget), pero no
lo escogimos porque es demasiado básico. Sólo cuida de manejar acontecimientos y
rendering, pero queremos más funcionalesity para libres. Todavía, esto es una clase
interesante para estudiar si quieres cavar a Odoo Javascript internals.
Escogimos AbstractField (definidos por web.La forma_común) porque trae toda la
funcionalidad necesitamos para nuestro widget a behave como campo de forma. Yot esto
por heredar de FormWidget e implementando FieldInterface, el cual incluye cosas
como comunicantes con la forma de padre, salvando el valor del campo actual, y tan
encima. Tendrías que estudiar ambas clases, pero la mayoría de funciones importantes
son overridden en el ejemplo de código para hacer este widget cualquier cosa en primer
lugar.
El init la función tendría que soler hacer tareas de inicialización síncrona. Entonces, para
inicialización asíncrona, cualquier uso willStart (carreras antes de rendering) o inicio
(carreras después de rendering). Ambos aquellas funciones están supuestas para regresar
un deferred objeto, el cual sencillamente obtenemos de super . Valor puesto_entonces
necesidades de tratar el valor del campo que el widget está supuesto para mostrar. Cuando
la clase de padre maneja los aspectos de almacenamiento, nosotros only tiene que cuidar
que está mostrado correctamente.
Utilizamos init para instalar una lista de usuarios (esto es sólo para mantenerlo sencillo por
ahora, generalmente, duro-coded el dato es una idea horrible naturalmente. Fijaremos esto en la
receta que Hace RPC llamadas al servidor) y para atar un acontecimiento. Otra posibilidad para
acontecimientos obligatorios está utilizando los acontecimientos de mapeo, donde te mapa un
nombre de acontecimiento, posiblemente seguido por un jQuery selector, a un nombre de función.
Utilizamos esto para tener los acontecimientos de clic para los botones creamos más tarde
instalados automatically.
El real UI está creado en inicio, donde sencillamente creamos un botón por usuario, y ha
puesto_el valor marca el botón apropiado con el btn_clase primaria. El dos
acontecimiento handlers botón_clicked y eficaz_readonly_cambió entonces es entonces
necesario de implementar nuestro widget comportamiento, aquello es, seleccionar el
usuario unas exhibiciones de botón, pero no deja selecciones en leer modo único.
329
Desarrollo de Cliente de la web
Nota que hay también una propiedad readonly y uno llamó eficaz_readonly.
Los abetost está puesto cuándo el campo está marcado tan leído sólo,
cualquiera en la definición de campo o la forma es. El último es la
conjunción del primer y restricciones eventuales por permisos encima
modelo o nivel récord, así que ser seguro para utilizar eficaz_readonly
cuándo hast o tratar widgets.
Después de que hemos definido nuestro nuevos widget, es crucial de registrar él con la forma
widget registro, el cual vive en web.Núcleo. Si quieres crear widgets para otros tipos de
vista, les tendrás que registrar en un registro apropiado, gusta
web.Núcleo.Lista_widget_registro o
Web.Núcleo.Búsqueda_widget_registro.
Finalmente, exportamos nuestro widget clase de modo que otro addons lo puede extender o
heredar de él.
El resto del código es algunos bastante unspectacular styling para nuestros botones,
registrando nuestro
JavaScript Y CSS archivos con el sistema, y utilizando nuestro widget en la forma de socio.
Allí ha más...
El namespace web.La forma_común define un par de muy útil mixin clases no tendrías
que perder fuera encima cuándo forma en desarrollo widgets. ReinitializeFieldMixin
offers Una interfaz sencilla para widgets aquello tiene que sacar todo DOM elementos y
reconstruirles cuándo cambiando entre exhibición (leído único) modo y editar modo.
CompletionFieldMixin Es la base para campos que conclusión de oferta, como el
muchos2un o muchos2muchas_etiquetas widgets.
Cuando campo widgets es responsable para valores gestores, son también responsables
para validación.
Uso las funciones es_válidas y es_sintaxis_válido de implementar vuestro
customizations de este aspecto. El último está significado para ser un control muy básico,
como el hecho que un campo de número sólo tendría que contener dígitos, mientras el
anteriores tener que también mirada en el cuadro más ancho, como el hecho que una
proporción tendría que ser menos de o igual a 1 y más grande que o igual a 0.
Ve también
En caso quieres utilizar algo muy similar a esto en vida real, tiene una mirada en el
radiofónico widget proporcionado por la web addon, apoya selección y muchos2un
campos.
Una fuente muy buena para más widgets es el repositorio comunitario
https://github.com/ OCA/web, donde los desarrolladores comparten su propósito
general widgets (y otro addons relacionó al cliente de web).
330
Capítulo 15
Preparándose
Esta receta es justo una versión modificada de la receta anterior, Crea hecho de encargo
widgets, código, tan grab una copia de él y utilizarlo para crear el módulo ch15_r02.
Ahora otro addons tiene un mucho tiempo más fácil que cambia el código de HTML
nuestro widget noses, porque pueden sencillamente override él con el habitual
QWeb patrones.
Cómo trabaja...
Tan hay ya una discusión comprensible del basics de QWeb en el Capítulo 14,
Desarrollo de Sitio web del CMS, la receta que Crea o modificando plantillas: QWeb, nosotros
focus en qué es diferente aquí. Ante todo, necesitas darte cuenta que estamos tratando el
Javascript QWeb implementación aquí tan opposed a la implementación de Pitón en el lado
de servidor. Esto significa que no tienes acceso para explorar registros o el environment; sólo
tienes acceso al actual widget vía variable widget y algunos helper objetos como datetime
con un subconjunto de Pitón cuando descrito en el Capítulo 8, Backend Vistas, la receta que
Pasa parámetros a formas y acciones: Contexto.
Esto significa que you tendría que tener toda la inteligencia en el widget código de Javascript y
tener vuestra plantilla propiedades de acceso único, o posiblemente funciones, en el widget.
Afortunadamente, la versión original de nuestro widget esto ya, así que la cosa única tenemos
que hacer est o iterar a través del objeto preparamos en init y crear botones
consiguientemente. Dado
Aquello también podemos llamar todas las funciones disponibles en el widget, sencillamente
lo podemos preguntar si tenga que behave tan leído-único por llamar el conseguir función,
el cual regresa las propiedades salvaron antes vía
PropertiesMixinEs (definido en web.mixins) Función de conjunto.
Cuando lado de cliente QWeb tiene nada para hacer con QWeb vistas, hay un mecanismo
diferente para hacer aquellas plantillas sabidas al cliente de web; les añade vía el clave
qweb a vuestro addon manifest en una lista de archivo nombra relativa al addon raíz.
Allí ha más...
La razón para hacer el esfuerzo para utilizar QWeb aquí era extensibility y esto es la segunda
diferencia grande entre lado de cliente y lado de servidor Qweb. En el lado de cliente, no puedes
utilizar Xpath expresiones, pero necesitas utilizar jQuery selectors y operaciones. Si nosotros, por
ejemplo, quiere
Para cambiar nuestro widget en aún así otro módulo, utilizaríamos el código siguiente para
tener cada cual de nuestros botones muestra un icono de usuario antes del nombre del
usuario:
<t t-Extender="FieldMany2OneButtons">
<t t-jquery="Botón" t-operación="prepend">
<i clase="fa fa-usuario" />
</t>
</t>
332
Capítulo 15
Ve también
El lado de cliente QWeb el motor ha menos mensajes de error conveniente y manejando que
otras partes de Odoo. Un error pequeño a menudo significa que sencillamente nada pasa y es
duro para principiantes
Para continuar de allí. Afortunadamente, hay algunos depura declaraciones para lado de
cliente QWeb templates describió más tarde en el capítulo, en la receta que Depura vuestro
código de lado del cliente.
Preparándose
Esta receta es justo una versión modificada de la receta anterior, Utilizando plantillas de lado
del cliente: QWeb código, tan grab un copy de él y utilizarlo para crear addon ch15_r03.
333
Desarrollo de Cliente de la web
Ahora tendrías que ver todos los usuarios de vuestro sistema, no justo el dos duro-coded
unos tan tú before. También, el widget puede ser utilizado para cualquier muchos2un
campos ahora, porque él justo consultas qué es disponible y no necesita cualquier
conocimiento sobre este por adelantado. Si pusiste un ámbito en el campo, los botones
serán restringidos a los registros que emparejan este ámbito. Yon este caso concreto,
podrías querer restringir la selección a usuarios del Usuario de Venta | del grupo.
334
Capítulo 15
Cómo trabaja...
El willStart la función se apellida antes de rendering, y, más importantly, regresa un deferred
objeto que tiene que ser resuelto antes de rendering inicios. Tan en a un caso le gustar el nuestro,
donde necesitamos correr una acción asíncrona antes de rending puede ocurrir, esto es la función
correcta para hacerlo .
De todas formas, tendremos que recoger los resultados asynchronously en nuestro éxito
handler. Esto instalará el usuario de estructura de dato interno_lista la misma manera
nosotros antes en el duros-coded versión, el cual es grande, because de este modo, no
tenemos que cambiar cualquier cosa más.
Nota que pedimos el nombre de exhibición_del campo aquí en vez de nombre , porque
podemos ser seguro que cada modelo tiene un nombre de exhibición_del campo, mientras
que aquello no es guaranteed con el nombre de campo. Entonces nosotros justo assign la
propiedad de nombre el mismo valor cuando nombre_de exhibición, esto, otra vez, es en
ordena no para tener que cambia existir código más de necesario. Hacer este demasiado en vez
de
Mucho overrides si justo necesitas desviar exhibición a otro campo o algo similar. Parad etails
sobre el campo_de nombre de la exhibición, refiere al Capítulo 4, Modelos de Aplicación,
receta
Definir la representación de Modelo y orden.
El fin del handler contiene la parte crucial, resolviendo el deferred objeto creamos antes de
que. Esto, en combinación con regresar el deferred el objeto envuelto junto con super
resultado en un nuevo deferred el objeto creado por el jQuery.Cuándo llamada, causa
rendering a sólo pasar después de los valores son fetched y cualquier acción asíncrona
super era ocupado con acabó también. ThEs manera, puedes ser seguro en el código de
plantilla que widget.Lista_de usuario es accesible y contiene los valores
necesitamos.
Allí ha más...
El AbstractField la clase viene con un par de propiedades interesantes, uno del cual
utilizamos encima. La propiedad de campo contains la producción de los campos del
modelo_consiguen función para el campo el widget está mostrando. Aparte de la llave
de relación que te das el comodel para x2x campos o el ámbito, también lo puedes
utilizar a consulta la cuerda del campo, medida o cualquier cosa otra propiedad puedes
poner en el campo durante definición de modelo.
Otra propiedad útil es opciones , el cual contiene el dato pasado vía el atributo de opciones
en la definición de forma. Esto es ya JSON parsed, así que puedes acceder le gusta
cualquier objeto.
335
Web Client Desarrollo
Ve también
Odoo RPC fuertemente confía en jQuery deferred objetos, así que no pueda ser repetido a
menudo bastante que te tendría que bucear a jQuery documentación sobre este:
https://api.jquery.com/ jQuery.Deferred
Preparándose
Añadiremos nuestras pruebas al addon desarrolló en las recetas anteriores, tan grab el
código de la receta que Hace RPC llamadas al servidor unnd puso él en un módulo nuevo
llame ch15_r04.
336
Capítulo 15
337
Desarrollo de Cliente de la web
widget.$el.Encuentra('botón').Mapa(función()
{
Regreso
jQuery.trim(jQuery(Este).Texto())
}).Consigue(),
['Administrador', 'Demo usuario'],
'Control si el widget muestra los usuarios
esperamos'
);
async_result()
;
});
})
});
Cuándo tú navigate a /pruebas/de web ahora, el cliente de web correrá todas las pruebas
disponibles. Tendrías que encontrar nuestra prueba en esta lista también, hopefully con un
resultado positivo. Dado muchas pruebas correrán allí, pueda ser más sencillo a unlso pase el
módulo quieres prueba. En nuestro caso, el camino sería
/Pruebas/de web?Módulo=ch15_r04.
Cómo trabaja...
Defines vuestras pruebas de Javascript en una manera muy similar a cómo harías código
de Javascript normal sabido a Odoo: llamas una función que consigue vuestro código como
parámetro.
En el caso de pruebas, esta función se apellida define_sección y espera un nombre
lógico para las pruebas para ser corridas, los paquetes de Javascript la prueba requiere (en
nuestro caso, justo necesitamos el código nuestro módulo proporciona, así que pasamos
['ch15_r04'] aquí), y una función que instala el los prueba.
TSu función está proporcionada con una función la prueba llamada y un objeto llamaron
simulados. La función de prueba es qué llamamos a de hecho declarar pruebas; recibe
un nombre para la prueba sola y la función que contiene el código de prueba. Esta función
será proporcionada con un afirmar objeto y todos los paquetes requerimos en la llamada
para definir_sección como parámetros.
338
Capítulo 15
Dentro de esta última función, el testaje real pasa. Necesitamos instalar un par de helper
objetos porque un widget espera mantenerse a base de una forma, el cual en vuelta
implementa una interfaz llamóFieldManager. Para simplicidad, proporcionamos una
implementación mínima de aquel en ordena no para tener que estirar una forma entera
cuando dependencia para nuestra prueba. Con este, podemos instantiate nuestro widget y
también pasarlo una versión idealizada de un parsed nodo de XML que sería la definición
del campo en la vista de forma.
Al final de la función, podemos sujetar nuestro widget al elemento de contenedor creamos,
llamada el renderElement función, y control si rendering caused el DOM elementos para
aparecer tan esperamos.
Para hacer aquellos controles, el afirmar el objeto tiene unas cuantas funciones como
iguales, deepEqual, notEqual y notDeepEqual , el cual todos tratan igualdad, pero
las variantes* profundas recurse a tipos compuestos como variedades y objetos. Entonces
hay vale y notOk cuáles pueden soler afirmar valor cierto o falso y echa , para afirmar una
función, echa una excepción segura o mensaje de error.
Allí ha más...
El código de ejemplo contiene dos peculiaridades qué marcas esta prueba más
complicated que otros; necesita pedir dato del servidor, y como consecuencia de
aquel, corrido asynchronously. Ambos retos de pose al marco de prueba.
Para fetching dato, Odoo ofrece un objeto llamó simulado, el cual podemos llenar con datos
que será re girado cuándo dato de peticiones del código del servidor. Tan qué aquí es asignar
una función de Javascript por servidor URL nuestro código de prueba está esperado a consulta y
tener la función regresa qué consideramos el resultado esperado. Entonces la prueba es si el
código de lado del cliente reacciona a este dato apropiadamente. Si vuestras marcas de código
de la prueba llama a funciones o modelos diferentes, o al mismo pero con parámetros diferentes,
esta función tendría que reaccionar a aquellos parámetros. Pero
Cuando nosotros dato leído sólo una vez, basta para añadir un handler para
/web/dataset/busca_leído, y podemos justo puede regresar un resultado fijo. Si
vuestro código propio implica más interacciones con el servidor, probablemente
necesitarás un más listo handler que de hecho miradas en sus parámetros y regresa
resultados diferentes para diffepeticiones de alquiler.
Entonces, debido a la llamada asíncrona, necesitamos decir el marco de prueba que nuestra
función que sale no es todavía el fin de la prueba por llamar afirma.async(). Esto regresa
una función estamos suponer para llamar exactamente una vez dentro de nuestro
asynchronous handler para notificar el marco de prueba que esta prueba concreta está
hecha.
Ve también
Desafortunadamente, en el tiempo de escribir, muchos del Javascript más complejo los módulos
comunitarios no son todavía emigrados a Odoo 9.0, tan no hay muchos ejemplos de pruebas de
lado del cliente en el salvajes. Consultar las pruebas del módulo de web para algunos ejemplos:
https://github.com/
OCA/OCB/Árbol/9.0/addons/web/prueba/estática.
339
Desarrollo de Cliente de la web
Preparándose
Esta receta no realmente confía en código concreto, pero si quieres ser capaz de
reproducir exactamente qué está yendo en, grab el código de la receta anterior.
Todo de este confía en vuestro navegador que ofrece funcionalidad apropiada para depurar.
Mientras todos los navegadores importantes que, we'll mirada única en Cromo aquí para
propósitos de manifestación. Para ser capaz de utilizar el depurar herramientas, les abre por
clicking el superior-botón de carta correcta y seleccionando
Más herramientas | de Desarrollador de las herramientas:
341
Web Client Desarrollo
Cómo trabaja...
Cuándo el depurador está abierto, tendrías que ver algo similar al siguiente screenshot:
Allí ha más...
Uso el tabulador de Elementos para inspeccionar el DOM representación de la página el
navegador actualmente exhibiciones. Esto probará útil de hacer tú familiar con el código de
HTML que existe widgets producto, pero también te dejas a play con clases y CSS atributos
en general. Esto es un recurso grande para probar cambios de diseño.
El tabulador de Red te das una visión general qué peticiones la página actual hecha y
cuánto tiempo tome. Esto es útil de depurar cargas de página lenta, cuando normalmente
verás el culpable en uno mira aquí, representado por una barra larga. Entonces puedes
comprobar en el lado de servidor por qué esta llamada toma mientras hace. También, esta
vista te ayudas para determinar si hace sentido a parallelize llamadas; esto parecería varios
largo bars, uno tras otro. Si seleccionas una petición, puedes inspeccionar el payload pasó
al servidor y el resultado regresaron, el cual te ayudas para representar fuera de la razón
para comportamiento inesperado en el lado de cliente. También verás los códigos de estado
de las peticiones locase, por ejemplo 404, en caso un recurso no puede ser encontrado, por
ejemplo porque tú misspelled un nombre de archivo.
Para otros navegadores, tendrás que mirada arriba de funcionalidad similar en la
documentación.
Firefox Por ejemplo tiene el muy potente firebug addon, el cual lets actúas la
mayoría del mencionó acciones.
Cuando declaró encima, la depuración deviene complicada apenas las operaciones asíncronas
están implicadas. Breakpoints Es de uso limitado aquí porque interrumpen ejecución de código y
la llamada stack no contendrá el pencaje donde un acontecimiento handler estuvo sujetado, pero
mayoritariamente interno jQuery funciones y la implementación del navegador del sistema de
acontecimiento. El Profiling el tabulador te ayudas aquí por mostrar llamada graphs, incluyendo
timings. Esto puede dar pistas en acontecimiento handlers apellidándose en el orden incorrecto.
Otra estrategia es para extender fuera consola.Declaraciones de registro durante vuestro
handlers para parcela una clase de llamada graph en la consola de Javascript. Antes de bucear a
este, tiene una mirada crítica en absoluto vuestro código hecho de encargo para comprobar si
olvidaste para regresar superresultado en caso es un deferred objeto. Esto es una causa muy
común de cronometrar problemas.
343
16
Despliegue de
servidor
En este capítulo, aprenderemos sobre las tareas siguientes:
Introducción
Hemos visto en Capítulo 1, Instalando el Odoo Entorno de Desarrollo, en la receta
instalación Fácil de fuente, y en Capítulo 2, Dirigiendo Odoo Casos de Servidor, en la receta
que Estandariza vuestro diseño de directorio del caso, cómo para instalar un entorno de
desarrollo. Los requisitos para un entorno de producción son ligeramente diferentes. Este
capítulo cubre las especificidades del despliegue de Odoo.
Preparándose
Esperamos que tienes un caso de desarrollo a punto. En esta receta, suponemos el siguientes:
Amonestación:
Si los archivos de configuración de vuestro proyecto include información
de seguridad como contraseñas, no tendrías que empujar el proyecto en
un servicio público como GitHub. Uso un interno Git repositorio o un
privado GitHub proyecto.
fEl servidor de despliegue está corriendo Debian Jessie (pero tenga que trabajar
con pequeñochange encima derivó distribuciones como Ubuntu; ve Capítulo 1,
Instalando el Odoo Entorno de Desarrollo, para más en este).
fTienesaccesode raíz al servidor final que utilizassho sudo. Si tú no,
tendrás queencontrar un administrador de sistema a assist tú en la
configuración.
f Sabes el final plenamente nombre de ámbito cualificado bajo qué el servidor será
accedido.
Cómo trabaja…
La mayoría de la receta es idéntico a qué está descrito en Capítulo 1, Installing el
Odoo Entorno de Desarrollo, pero hay unas cuantas diferencias claves.
Estamos utilizando un usuario de sistema dedicado con login odoo. Esto nos habilito
para controlar quién tiene acceso a la cuenta, por ejemplo, por configurar el sudo o
ssh autorizó llaves. También nos dejo para dar este usuario cuando pocos permisos
como posibles, en caso el caso es compromised.
El usuario de base de datos enlazó a esta cuenta no tiene cualquier privilegio, ni siquiera
creación de base de datos. Creamos la base de datos externally, justo una vez. En caso el
enstance es compromised, un atacante no será capaz de crear bases de datos adicionales
en el servidor.
El Odoo guión estamos creando será utilizado en la receta Instalada Odoo como servicio
de sistema más tarde en este capítulo. Utiliza la producción.conf Archivo de configuración,
el cual está explicado en la receta próxima, Adaptando el archivo de configuración para
producción.
Nosotros uninstall gcc al final del proceso de modo que si un acceso de beneficios
atacante, no sea capaz de utilizar esto a recompile executables localmente.
Al final de esta receta, vuestro servidor no es a punto todavía. Necesitarás referir a las
recetas
Adaptando el archivo de configuración para producción, Instalado Odoo como servicio de
sistema, y
Configurar un inverso proxy y SSL, los cuales están descritos en este capítulo.
Allí ha más…
Aquí es unos cuantos puntos más importantes para considerar cuándo preparando
el despliegue de vuestro caso.
Dimensionamiento de servidor
Qué tiene que utilizas para un servidor? Más o menos servidor muy físico estos días es de
sobra para manejar una media sized Odoo ingenio de casoh aproximadamente 10 usuarios
simultáneos. Desde las máquinas virtuales típicamente tienen menos recursos provisioned,
necesitarás pagar un poco más atención a esto si estás planeando correr en un VM. Aquí
es unas cuantas figuras claves para conseguirte empezaron. Evidentemente, ellos need
multa poner a punto para emparejar vuestro uso de Odoo.
Un pequeño Odoo necesidades de caso al menos 1 GB de RAM. No es tímido en este; la
última cosa quieres pasar es vuestro intercambio de servidor. 2 a 4 GB es un punto de
partida bueno. Dar vuestro servidor, en el muy menos, dos CPU/núcleos. Si estás corriendo
el PostgreSQL servidor en el mismo anfitrión, provisión al menos cuatro CPU/núcleos, y
añadir 1 GB de RAM para la base de datos. El adicional CPU/los núcleos serán utilizados
por el Odoo trabajadores que está cubierto en la receta próxima, Adaptando el configuration
archivo para producción.
348
Capítulo 16
PostgreSQL Sintonía
Hablando PostgreSQL la sintonía es allende el alcance de este libro. Puedes querer
comprobar los libros PostgreSQL 9 Admin Recetario o PostgreSQL 9.0 Rendimiento Alto,
ambos de Packt Editorial, para un en-cobertura de profundidad de este temas.
El default configuración de PostgreSQL es generalmente muy conservador y significado para
impedir el servidor de base de datos de hogging todos los recursos de sistema. Encima
servidores de producción, sin incidentes puedes aumentar algunos parámetros en el
postgresql.conf Archivo para conseguirapostado ter rendimiento. Aquí es algunos
encuadres puedes utilizar para empezar:
max_Conexiones = 100
compartió_buffers = 256MB
eficaz_cache_medida = 768trabajo
de MB_mem = 10mantenimiento de
MB_trabajo_mem = 64punto de
asistencia de MB_segmentos = 16
wal_buffers = 8punto de asistencia
de MB_conclusión_target = 0.9
$ pgtune -T OLTP -i
/Etc/postgresql/9.4/principal/postgresql.conf \ -M 1073741824
-c 100
Por qué no utilizar los paquetes de distribución del Linux proporcionados por
Odoo?
Puedes hacer aquel y empezarás mucho más rápido porque muchas cosas
están manejadas para tú por los paquetes. Aun así, hay unos cuantos asuntos
con utilizar el packaged fuente; la mayoría deimpo rtantly, puedes no fácilmente
remendar el código de fuente de Odoo, el cual es más fácil si te corrido de la
fuente. Concedido, esto no es algo tienes que hacer todos los días, pero siendo
capaz de utilizar las herramientas de desarrollo estándares para conseguir esto,
más que manualmente applying y siguiendo remiendos encima servidores de
producción, es una ayuda preciosa y un beneficio de tiempo. También puedes ser
utilizando el Odoo rama de Asociación Comunitaria de Odoo, (https://
github.com/OCA/OCB) Para qué ninguno paquetes están proporcionados.
Copias de seguridad
La receta no cubre copias de seguridad. En el muy menos, tendrías que tener el cron
tarea en el servidor que corre una copia de seguridad diaria. Una solución sencilla y básica
es para editar el crontab archivo cuando raíz por running crontab -e y para añadir las
líneas siguientes:
@Diario su postgres -c pg_dumpall | gzip > /copias de
seguridad/postgresql-$(fecha +%u).dump.gz
@Alquitrán diario czf /copias de seguridad/odoo-datos-$(fecha
+%u).tgz /Casa/odoo/odoo-prod/dato/de proyecto
350
Capítulo 16
Ve también
Para más información en el Odoo rama de Asociación Comunitaria de Odoo, ver la receta
Instalación fácil de fuente en Capítulo 1, Instalando el Odoo Entorno de Desarrollo.
Adaptando el archivo de
configuración para producción
En Capítulo 1, Instalando el Odoo Entorno de Desarrollo hemos visto cómo para salvar la
configuración del caso en un archivo. Utilizamos el default valores para muchos parámetros,
y si has seguido el Estandarizar vuestro caso directory receta de diseño en Capítulo 2,
Dirigiendo Odoo Casos de Servidor, así como la receta anterior para la instalación de
producción, ahora tendrías que tener que archivo de configuración misma en el entorno de
producción. Estos espectáculos de receta cómo para derivar un configuratel ión archiva
aquello es propio para uso en producción.
Preparándose
Suponemos que te ha instalado Odoo en el servidor de producción con la receta anterior,
Instala Odoo para producción. Suponemos que serás correr PostgreSQL en el mismo
servidor cuando Odoo.
6. Configura rotación de
registro: logrotate =
Cierto
352
Capítulo 16
Cómo trabaja…
La mayoría de los parámetros mostrados en esta receta está explicada en el Dirigir
Odoo receta de casos del servidor en Capítulo 1, Instalando el Odoo Entorno de
Desarrollo.
En pasos 3, 4, y 5, cambiamos el addons camino unnd el archivo de registro. En caso estás
desarrollando en un entorno con el mismo diseño como el entorno de producción, esto está
requerido porque Odoo espera caminos absolutos en el archivo de configuración.
Paso 6 habilita rotación de registro. Esto causará Odoo a configure el logging módulo a
archivo los registros de servidor en una base diaria, y para mantener los registros viejos
para 30 días. Esto es útil encima servidores de producción para evitar registros finalmente
consumiendo todo el disco disponible espacio.
Paso 7 configura el logging nivel. El encuadre propuesto es muy conservador y sólo mensajes de
registro con al menos el nivel de AVISO, excepto werkzeug (CRÍTICO) y openerp.
Servicio.Servidor (INFO). Para más información en el registro que filtra, refiere a Capítulo
7,
Depuración y Testaje Automatizado, whantes de ti encontrará la receta, Produciendo
registros de servidor para ayudar depurar métodos. Siente libre de poner a punto esto a
vuestro gusto.
Paso 8 configura los encuadres de base de datos. Esto trabajará si estás corriendo el
PostgreSQL servidor de base de datos localmente y lo ha instalado tan explained en la
receta anterior. Si estás corriendo PostgreSQL en un servidor diferente, necesitarás
reemplazar los valores Falsos con los encuadres de conexión apropiados para
vuestro caso de base de datos.
353
Despliegue de servidor
Paso 9 restringe la base de datos unvailable al caso por configurar un filtro de base de datos.
También inutilizamos el listado de base de datos, el cual no es estrictamente necesario
dado que la expresión regular pusimos en dbfilter sólo puede emparejar uno base de
datos sola. Es todavía una cosa buena para hacer aun así, para evitar mostrando la lista
de bases de datos a cualquiera, y para evitar los usuarios que conectan a la base de datos
incorrecta.
Paso 10 conjuntos un nontrivial contraseña maestra para el caso. La contraseña maestra
está utilizada para administración de base de datos a través de la interfaz de usuario, y
unos cuantos comunitario addons también utiliza él para seguridad extra antes de actuar
acciones que puede dirigir a pérdida de dato. Realmente necesitas poner esto a un
nontrivial valor. Proponemos utilizar el pwgen utilidad para generar una contraseña
aleatoria, pero cualquiera otro método esun lso válido.
Paso 11 configura Odoo para trabajar con trabajadores . En este modo, Odoo creará un
número de procesos de trabajador (en este ejemplo, 4) para manejar peticiones de HTTP.
Esto tiene varias ventajas sobre el default configuración en qué la petición que maneja está
actuado en hilos separados, los cuales están dados como sigue:
f Las peticiones pueden ser manejadas en paralelo, haciendo uso mejor de núcleos
múltiples o CPUs en el servidor (hilos de Pitón están penalizados por la existencia
de las Cerraduras de Intérprete Globales (GIL) ent él intérprete de Pitón).
f Es posible de rescindir uno de los trabajadores que dependen de consumo de
recurso.
La mesa siguiente da el varios recurso limita que puede ser configurado:
354
Chapter 16
Allí ha más…
Cuándo corriendo con trabajadores, puedes encontrar algunos emite concretos a este modo:
fSi consigues errores extraños cuándo corriendo con trabajadores, con lessco
wkhtmltopdfno trabajando tan pretendidos (por ejemplo, prematuramente
saliendo con un -11 o -6 estado), entonces probablemente tienes memoria_de
límite_conjunto duro a un valor que es demasiado abajo. Prueba levantar lo un
poco, cuando el default el valor es notoriamente demasiado abajo.
fSi consigues timeout errores cuándo actuando operaciones largas (esto incluye CSV
importacionesy exportacións y addon instalaciones de módulo), prueba aumentar
el tiempo_de límite_cpu y tiempo_de límite_parámetros reales, tan allí
demasiado el default el valor es bastante abajo. Si tienes un inverso proxy, puedes
querer comprobar su timeout límite también (a pesar de que esto no impedirá elt
ransactions de completar).
fSi vuestro caso consigue completamente enganchado cuándo imprimiendo
informes, prueba levantar el númerode trabajadores. Esto puede ser un punto
muerto causado por wkhtmltopdf bloqueando arriba todos los trabajadores
disponibles mientras imprimiendo.
Preparándose
Suponemos que seguiste el abetost dos recetas para instalar y configurar vuestro Odoo caso.
Especialmente la fuente desplegada de Odoo, el cual es en /casa/odoo/odoo-
prod/proyecto/ src/odoo/, y el archivo de configuración del caso, el cual es en
/casa/odoo/odoo-prod/producción/de proyecto.conf. Los guiones también hace
uso del inicio-odoo el guión creado en paso 9 del Instalar Odoo para receta de
producción.
Primero necesitarás descubrir qué sistema de inicialización está corriendo en vuestro
sistema. Para este, corrido el siguiente:
$ dpkg -l systemd
Si la última línea de inicios de producción con ii systemd, entonces systemd es disponible
en vuestro sistema. Otherwise, probablemente estás corriendo sysvinit (en un sistema
que corre un viejo Debian variante) o upstart (en un Ubuntu-sistema basado).
355
Despliegue de servidor
[Servicio]
El tipo=sencillo
Usuario=odoo
Grupo=odoo ExecStart=/casa/odoo/odoo-prod/inicio/de
cubo/del proyecto-odoo
[Instala] WantedBy=multi-
usuario.Objetivo
356
Capítulo 16
2. Cuando raíz, edita que file para cambiar las variables de entorno definieron en la
parte superior del guión (sólo listamos los cuáles necesitan cambiar como sigue,
con los valores apropiados):
DAEMON=/Casa/odoo/odoo-prod/inicio/de cubo/del proyecto-odoo
Cómo trabaja…
Las tres configuraciones, systemd, sysvinit, y upstart , uso algunos archivos de
configuración o guiones para saber cuál programa must corrido cuándo las botas de servidor.
Las configuraciones proporcionadas en la receta necesitará adaptaciones pequeñas para
emparejar los caminos de vuestro caso.
Allí ha más…
Si estás utilizando el buildout el método descrito en el Uso buildout para repeatable receta
de complexiones, necesitarás adaptar los caminos para utilizar el inicio_odoo el guión
creado por la receta.
Preparándose
Tendrías que saber el nombre público del servidor y configurar vuestro DNS
consiguientemente. En esta receta, utilizaremos odoo.example.com cuando el nombre
de vuestro servidor.
Si quieres vuestro Odoo caso para ser visible por todos los navegadores, necesitarás
conseguir un SSL el certificado firmado por una Autoridad de Certificación reconocida
(CA). Utilizando un self-el certificado firmado también puede ser hecho para trabajar, pero
los navegadores modernos tienden para rechazar estos.
Para generar un SSL llave, puedes utilizar el proceso siguiente:
1. Instala openssl:
$ sudo Apto-conseguir instalar openssl
358
Capítulo 16
Ubicación / {
Reescribe ^/(.*) https://odoo.example.com:443/$1 permanente;
}
}
Ubicación / {
proxy_Http de
pase://localhost:8069;
proxy_leído_timeout 6h;
proxy_conecta_timeout 5s;
proxy_Redirige http://$http_https/
anfitrión://$anfitrión:$puerto_de servidor/;
añade_encabezamiento X-Estático no;
proxy_buffer_Medida 64k;
proxy_buffering fuera;
proxy_buffers 4 64k;
proxy_ocupado_buffers_medida
64k;
359
Despliegue de
servidor
proxy_intercept_Errores encima;
}
Ubicación ~ /[un-zA-Z0-9_-
]*/estático/ { proxy_http de
pase://localhost:8069;
proxy_cache_válido 200 60m;
proxy_buffering encima;
Expira 864000;
}
}
6. Cuando raíz, copia el ssl certificado y llave de servidor a los directorios apropiados
# mkdir -p /Etc/nginx/ssl
# chown www-Datos /etc/nginx/ssl
# mv Servidor.Servidor clave.crt /Etc/nginx/ssl
# chmod 710 /etc/nginx/ssl
# chown Raíz:www-datos /etc/nginx/ssl/*
# chmod 640 /etc/nginx/ssl/*
Cómo trabaja…
Estamos utilizando nginx como HTTP inverso proxy. Incoming HTTP y conexiones de HTTPS
están manejados por nginx, el cual delega el procesamiento de las peticiones al Odoo
servidor. El
Odoo El servidor está configurado a sólo escuchar en el lugareño loopback interface
(127.0.0.1) en portuario 8069 para peticiones normales (xmlrpc_portuarios) y puerto
8072 para el largo encuestando peticiones (longpolling_portuarios). Puedes necesitar
adaptar los números portuarios a vuestra configuración.
La receta instala dos archivos. El primer ene es la configuración para incoming conexiones en
portuarios
80 utilizando el protocolo de HTTP. No queremos estos porque son en texto claro,
significando que las contraseñas pueden ser husmeadas. Por tanto, instalamos nginx para
redirigir el URLs permanentemente a puerto 443 using el protocolo de HTTPS encriptado.
El segundo archivo es un poco más complejo y configura la manera nginx tendría que
manejar las conexiones que utilizan el protocolo de HTTPS:
fEl primer bloque de configuración configura el SSL protocolo, la llave de
encriptación, y certificado, cuandow ell como la ubicación del archivo de
registro.
fLos segundos conjuntos de bloque algunos encabezamientos en las peticiones
para manejar el apropiados inversosproxying encima HTTPS.
fElbloque /de ubicación define el default procesamiento de incoming peticiones;
seránproxied al Odoo servidor listening en portuario 8069.
fLa ubicación /longpollingconsultas de mangos del bloque hicieron en URLs
empezando con /longpolling, los cuales son entonces enviados a Odoo en
portuarios 8072. Estas conexiones están utilizadas por el autobús addon módulo para
enviar notificaciones al cliente de web.
fLa ubicación ~ /[un-zA-Z0-9_-]*/el bloque/estático utiliza una expresión
regularpara emparejar el URLs de los archivos estáticos de Odoo módulos. Estos
archivos son raramente actualizados, y tan preguntamos nginx a cache les para aligerar
la carga en el Odoo servidor.
361
Despliegue de servidor
Allí ha más…
Este foco de receta en el nginx configuración. Puedes ser más familiar con otras
herramientas como el servidor de web del apache y mod_proxy . En este caso,
naturalmente puedes utilizar estos para conseguir un similar setup.
Ve también
fPara másinformación sobre el varios nginx opciones de configuración,
vehttp://nginx.org/en/docs/.
fPara un preceptoral en la configuración de apache2 como inverso proxy y el uso de
unacertificación personal authority, tomar una mirada en
http://antiun.github.io/odoo-
Inverso-proxy-howto/.
Estos espectáculos de receta cómo puedes empezar utilizar buildout para asegurarte ha
igual setup en el desarrollo y servidores de producción.
Preparándose
Suponemos que vuestro caso sólo tiene una dependencia en el servidor-proyecto de
herramientas del
Odoo Asociación Comunitaria, y que vuestro usuario-concreto addon los módulos
están viviendo en el locales/addons subdirectorio del proyecto.
También te esperamos para tener instalado las dependencias de complexión de Odoo.
Refiere a pasos 1 a 3 del Instalar Odoo para producción recipe en este capítulo. Esta receta
es mejor utilizado primero en una máquina de desarrollo y más tarde desplegado en un
servidor de producción.
362
Capítulo 16
[odoo]
Receta =
anybox.Receta.odoo:Servidor OCA =
https://github.com/oca
Versión = git https://github.com/odoo/odoo.git odoo 9.0
profundidad=1 addons = git ${odoo:OCA}/servidor-herramientas.git
Separa/servidor-herramientas 9.0 git ${odoo:OCA}/socio-
contacto.git Separa/socio-contacto 9.0
Local local/addons
Opciones.Memoria_de límite_dura =
4294967296 opciones.Memoria_de
límite_blanda = 671088640
opciones.Petición_de límite = 8192
opciones.Tiempo_de límite_cpu = 120
opciones.Tiempo_de límite_real = 300
opciones.xmlrpc_Puerto = 8069
opciones.longpolling_Puerto = 8072
opciones.Trabajadores = 0
[versions]
zc.buildout = 2.5.0
anybox.buildout.odoo = 1.9.1
setuptools = 19.7
Babel = 1.3
Jinja2 = 2.7.3
Mako = 1.0.1
MarkupSafe = 0.23
Almohada = 2.7.0
363
Despliegue de
servidor
Pitón-Gráfico =
1.39 PyYAML = 3.11
Werkzeug = 0.9.6
argparse = 1.2.1
decorator = 3.4.0
docutils = 0.12
feedparser = 5.1.3
gdata = 2.0.18
gevent = 1.0.2
greenlet = 0.4.7
jcconv = 0.2.3 lxml
= 3.4.1
Simulado = 1.0.1
ofxparse = 0.14
passlib = 1.6.2
psutil = 2.2.0
psycogreen = 1.0
psycopg2 = 2.5.4
pyPdf = 1.13
pydot = 1.0.2
pyparsing = 2.0.3
pyserial = 2.7
Pitón-dateutil = 2.4.0
pitón-ldap = 2.4.19
pitón-openid = 2.2.5
pytz = 2014.10
pyusb = 1.0.0b2
qrcode = 5.1
reportlab =
3.1.44 peticiones
= 2.6.0 seis =
1.9.0 suds-jurko
= 0.6 vatnumber =
1.2 vobject =
0.6.6 wsgiref =
0.1.2 xlwt =
0.7.5
364
Capítulo 16
[odoo]
Opciones.Memoria_de límite_dura =
4294967296 opciones.Memoria_de
límite_blanda = 671088640
opciones.Petición_de límite = 8192
opciones.Tiempo_de límite_cpu = 120
opciones.Tiempo_de límite_real = 300
opciones.Trabajadores = 4
Opciones.xmlrpc_Interfaz = 127.0.0.1
opciones.netrpc_Interfaz = 127.0.0.1
opciones.xmlrpc_Puerto = 8069
opciones.longpolling_Puerto = 8072
Opciones.listdb = Falso
options.db_anfitrión = Falso
options.db_portuario = Falso
options.db_el usuario = Falso
options.db_nombre = odoo_opciones
de proyecto.dbfilter =
^odoo_Proyecto$ opciones.proxy_El
modo = Cierto
365
Despliegue de
servidor
[odoo]
options.db_Nombre = odoo_dev
optaiones.dbfilter =
^odoo_dev$ Opciones.Nivel_de
registro = info
Cómo trabaja…
Buildout Trabajos por procesar un archivo de configuración, el cual se apellida
buildout.cfg Por default.
Este archivo utiliza una sintaxis cierra a ConfigParser (con unas cuantas extensiones) para
describir el entorno de objetivo deseado. Hay uno sección obligatoria, [buildout], el cual
contiene una entrada de partes que lista las secciones para procesar. La mayoría de secciones
tienen una entrada de receta que da el nombre de un buildout receta para utilizar para
construir la sección. Hay muchas recetas disponibles (toma un
Mirada en http://www.buildout.org/en/latest/docs/recipelist.html para un
listado parcial), y las recetas diferentes pueden ser combinadas en un archivo de
configuración solo. Each La receta apoya sus encuadres de configuración propios. Las
recetas son módulos de Pitón , normalmente hechos disponibles de PyPI.
Buildout Archivos de configuración son extensibles y soporte parameterization:
367
Despliegue de servidor
Para correr buildout, justo ejecutar el cubo/buildout guión con el -c opción para
especificar un archivo de configuración. Esto hará varias cosas:
f Odoo Consigue instalado en el subdirectorio/ de partes
fEl especificado addons está instalado en el subdirectorio especificado (
recomendamos que utilizas partes/ para este también)
fLas dependencias de Odoo y cualesquier dependencias adicionales están
instaladas ensubdirectorio/ de huevos
fUn archivo de configuración está creado enetc/odoo.cfgCon el valor
apropiado paraaddons_el camino y todas las opciones especificaron en el
buildout configuraciones
fUn helper iniciode cubo/del guión_odooestá creado; utiliza el archivo de
configuración generadoy las dependencias de Pitón instaladas
Allí ha more…
Si uno addon módulo que te la necesidad requiere una dependencia de Pitón externa, lo
puedes añadir al [odoo] la sección que utiliza los huevos que ponen. Para caso, para añadir
unicodecsv al buildout, uso el siguiente:
[odoo]
Huevos += unicodecsv
[Versiones]
unicodecsv = 0.14.1
368
Capítulo 16
Provisional fusiona
Durante desarrollo, pueda ser útil de fusionar peticiones de atracción pendiente en los
varios proyectos utilizaron por el proyecto. El buildout la receta apoya esto a través del
fusiona opción. Suponer vuestro proyecto utiliza OCA/socio-contacto y OCA/producto-
atributo, y necesitas fusionar el PR 237 y 249 encima socio-contacto y el PR 132 encima
atributo de producto, entonces puedes escribir el siguiendo en vuestro buildout archivo de
configuración:
[odoo]
OCA = https://github.com/oca
version = git https://github.com/odoo/odoo.git odoo 9.0 profundidad=1
addons = git ${odoo:OCA}/socio-contacto.git Separa/socio-contacto 9.0
git ${odoo:OCA}/Producto-atributo.git Separa/producto-atributo
9.0
Fusiona = git socio de partes/del origen-atracción de
contacto/237/cabeza git socio de partes/del origen-
atracción de contacto/249/cabeza
git Producto de partes/del origen-atracción de atributo/132/cabeza
La sintaxis para el fusionar la opción que utiliza el git el protocolo es repositorio> <local remoto
<> <refspec>. Utilizamos aquí la referencia para atracción pide proporcionada por GitHub.
Congelando un buildout
A ease despliegue, es posible de utilizar algunos adelantaron órdenes. La congelación-a la
opción puede soler generar un buildout archivo de configuración que congelaciones las
revisiones de Odoo y todo el addons:
$ Cubo/buildout -c prod.cfg -o odoo:Congelación-a=congelado-prod.cfg
You Puede entonces corrido buildout con el congelado-prod.cfg Archivo para conseguir
las versiones mismas exactas de los archivos.
También puedes extraer el código de fuente a un directorio separado, con el extracto-
descargas-a opción:.
$ Cubo/buildout -c congelado-prod.cfg \
-o odoo:Extracto-downloads-a=../Producción
369
Despliegue de servidor
Ve también
f La documentación llena para el buildout la receta es disponible en http://docs.
anybox.fr/anybox.recipe.odoo/current/index.html.
370
Utilizado, para elementos de forma dinámica
207
Automatizó acciones
Utilizando, encima el acontecimiento
condiciona 288-291 utilizando,
puntualmente condiciona 283-287
Símbolos
@api.Un decorator 98, 99
Un
Modelos abstractos
Utilizando, para el modelo reutilizable
presenta 89-91
Control de acceso lista
127 acciones
ir.Acciones.Ventana_de
acto.Vista 185 parámetros,
paso 190-193 vista concreta,
abriendo 184, 185
addon Módulo
Cambios, applying 42, 43
creando 48, 49
El dato archiva 54
Estructura de archivo,
organizando 52-55 instalando
48, 49
Instalando, de GitHub 40, 41
lista, actualizando 31-33
manifiesta, acabado 49-52
Código de pitón
54 versus addon
29 ventajas de
web 54
addons El camino
que configura 30,
31
addon updates 229-231
API Código
Viejo API código, porting a nuevo API
143-151
API decorators
Definiendo 96-98
attrs Atributo
Depuración 340-343
pruebas, escribiendo para
336-339
Cliente-lado QWeb las
plantillas que utilizan
Índice
331-333
Línea de ordeni nterface
157 repositorio comunitario
URL 330
B
backups 351 371
base_suspende_se
guridad
URL 127
bootstrap
URL 318
buildou
t
Aproxi
mada
ment
e 362
Helado 369, 370
provisional
mergess 369 URL
367, 370
Utilizando, para repeatable complexiones
362-368
Construido-en workflows
Inspeccionando 291-294
Lógica empresarial
En modelo, extendiendo 114-117
Botones
Añadiendo, a formas 189, 190
C
El calendario ve
212, 213 categoría
URL 51
Autoridad de certificación (CA)
Aproximadamente 358
Personal
362
cliente-
código de
lado
Computó campos Dependencias 4
Añadiendo, a modelo 82-84 herramientas de
configurable Precisión desarrollador
Campo de flotador, utilizando con 71, 72 Activando 22-24
Configuración Documento-el estilo forma 205, 206
Adaptando, para producción 351-355
Validaciones de
constreñimiento que
añaden, a modelo 80,
81
content
Añadiendo, para formar vista 186
Contexto
Utilizado, para computar default valores
136
Nodo de contexto
203 crea()
Extendiendo 117-120
CSS
Extendiendo, para sitio web 311-313
CSV Archivos
Utilizado, para cargar dato 226,
227 hecho de encargo widgets
Creando 325-330
D
Dato
Cargando, CSV los archivos
utilizaron 226, 227 cargando,
XML archivos utilizaron 221-224
cargando, YAML los archivos
utilizaron 228, 229
Campos de dato
Añadiendo, a modelo 66-70
El dato archiva 54
Migración de dato 229-
232 datetime módulo
de Pitón
URL 275
dbfilter_de_encabeza
miento
URL 300
Debian Jessie
URL 3 decorators
97 Deferred objeto
330
Herencia de delegación
Utilizando, para copiar características a otro
modelo 91
Duplicidad La interfaz utilizó 91-
URL 351 93 siguiendo 276-280
Elementos de forma dinámica Campos
attrs Utilizó 207 En modelos, el límite que accede 241, 242
Relaciones dinámicas Archivo
Undding, campos de referencia utilizaron Configuración de caso, almacenando 19-22
86, 87 estructura para addon módulo, organizando
52-55
E Filtros
Definiendo, enr ecord listas 193-
Eficaz_readonly propiedad 195 pitfalls 196
330 emacs (po-modo) Campo de flotador
URL 264 Utilizando, con configurable precisión 71, 72
embedded Ve 207, 208 forcecreate Las
errores banderas que
Informando, a usuario utilizan 224-226
99, 100 externo IDs Formas
Utilizando 219-221 Botones, añadiendo 189, 190
parámetros, paso 190-193
F Botón de
vista de la
Características
Activando, grupo de seguridad utilizó forma 187
246-251 añadiendo a modelo, Contenido,
inheritance utilizó 87-89 copiando a añadiendo 186
otro modelo, delegación campo 188
Formas 187
General entributos 188
372
Grupos 187 Extendiendo, para sitio web 311-313
encabezami jQuery
ento 187 URL 336
Otras etiquetas 188, JSONRPC 309
189 widgets,
añadiendo 186
congelación-a opción
369
G
gettext Herramientas
Utilizando, para aliviar traducciones 264
Git
Aproximadame
nte 4
configuración 7
GitHub
addon Módulos, instalando 40,
41 URL 2, 256
Graphvi ews 213-215
Gtranslator
URL 264
H
handler
Existiendo handler, modificando 304-306
Elemento de
cabeza 313 nodo
de cabeza 313
jerarquía
Añadiendo, a modelo 78, 79
Estado de HTTP 500 100
Yo
Herencia
Utilizado, para añadir características a
modelo 87-89
Configuración de caso
storing, en archivo 19-21
Diseño de directorio del
caso standarizing 33-
35
ipdb
URL 164
J
Javascript
K Línea de orden utilizó
38 instalando 36-39
Kanban actualizando 39, 40
Tabler upgrading 36
o 271 Interfaz de web utilizó 36,
Tarjetas, mostrando en columnas 37 logging nivel 156
según estatales 211 Registro handler 156
Característica Lokalize
s 270-272 URL 264
etapas 270-
272 estado M
272
Vistas 209, 210 Manifiesta
addon El módulo manifiesta, acabado 49-52
L Elementos de carta
Añadiendo 57-61, 180-
Lengua 183 messaging
Instalando 253-256 Añadiendo 276-280
La lengua relacionó encuadres Método
Configurando 257, 258 La ejecución que localiza,
Menos depurador de Pitón utilizó
URL 314 159-164
Paquetes de distribución del Linux Depuración, por producir registros de servidor
URL 350 153-156 con contexto modificado, llamando
La lista ve 196- 128-130
198 local addon microdata
módulos URL 318
373
Modelo Copias de seguridad 350, 351
Añadiendo 55-57 Git, configuración 7
Lógica empresarial, extendiendo Instalando, para producción
114-117 computó campos, 345-348 instalando, de fuente
añadiendo 82-84 validaciones de 2-5 caso, empezando 7, 8
constreñimiento, añadiendo 80, 81 PostgreSQL Configuración 6, 7
campos de dato, añadiendo 66-70 PostgreSQL Sintonía 349, 350
Las características que añaden, la herencia
utilizó 87-89 características que copian a otro
modelo, delegación
La interfaz utilizó 91-93
campos, el límite que accede
241, 242 jerarquía, añadiendo
78, 79 métodos, definiendo
96-98 campo monetario,
añadiendo 73 orden,
definiendo 64-66
Relacionó los campos
almacenaron, exponiendo 85
campos relacionales, añadiendo
74-77 representación, definiendo
64-66 acceso de seguridad,
añadiendo 238-241
Módulo
Creando, scaffold utilizó 61, 62
Pruebas de módulo
Escritura, pruebas de unidad de la
Pitón utilizaron 168-171 escritura,
YAML utilizó 164-167
El campo monetario
que añade, a
modelo 73
N
namespaces
Utilizando 219-
221
nginx
Opciones de configuración, URL 362
URL 357
noupdate
Aproximadame
nte 317
utilizando 224-
226
O
Odoo
Servidor, dimensionamiento 348, Utilizado, para interactivamente llamando
349 instalando, cuando servicio de métodos 157, 158
sistema 355 código de fuente, Odoo superuser 127
descargando 7 código de fuente onchange métodos
versión 350 Aproximadamente 104
Empezando, systemd configurando para Llamando, encima lado de
356 empezando, sysvinit o upstart servidor 141, 142 definiendo
configurando para 138, 139
356, 357 Operadores 195
Actualizando, de fuente 25, 26
URL 323 P
Entornos virtuales (virtualenv) 5, 6
Odoo Asociación comunitaria (OCA) Parámetros
Aproximadamente 8, 29, 173 Pasado a handlers, consumiendo 302-
maintainer Herramientas de calidad, 304 paso, a acciones 190-193
utilizando 173-178 Paso, a formas 190-193
Odoo Herramientas de desarrollador Camino
Activando 22-24 accesibility, de red 295-297
Odoo Entornos openerp.Http.Petición 299
Gestor, orden de inicio utilizó 9, 10 openerp.Http.Ruta 297
Odoo maintainers El regreso valora 297, 298
URL 5 pdb
Odoo Bases de datos de URL 164
servidor que dirigen 10, El pivote ve 213-215
11 poedit
Odoo Concha URL 264
374
PO Manipulación de archivo Reglas
URL 266 récord
PostgreSQL Configuración 6, aproxima
7 PostgreSQL sintonía 349, damente
350 campo de prioridad 313 127
Producción Utilizado, para acceso récord limitativo
Configuración, adaptando 351-355 243-246
Odoo, instalando 345-348 Registros
pudb Registros nuevos, creando
URL 164 102-104 búsqueda,
peticiones personalizando 120-123
de atracción buscando 107, 108
Aproximadame
nte 43, 44
aplicando 43,
44
Código de pitón 54
Acciones de Servidor de
código de pitón que
utilizan 281, 282
Depurador de pitón
Utilizado, para localizar ejecución de método
159-163
Pruebas de unidad de la pitón
Utilizado, para escribir el módulo prueba
168-171
Q
QUnit
URL 336
QWeb
Aproximadament
e 314, 315
atributos 316
conditionals 316
campos 316
inline Editando
317 bucles 316
informes 215-
217
R
readonly Propiedad
330 acceso récord
Reglas limitativas , récord utilizaron 243-
245
Listas récord
Filtros, registro 193-195
recordsets RPC Llamadas
Peinando 109, 110 Haciendo, a servidor 333-336
Vacío recordset, consiguiendo para modelo RPC Interfaz
diferente 101, 102 Métodos, escondiendo de 98
Filtrando 110-112
Valores de registros, actualizando S
104-107 relationes, traversing
112-114 scaffold
Campos de referencia Utilizado, para crear módulo 61, 62
Utilizado, para añadir relaciones dinámicas La búsqueda ve 198
86, 87 Seguro_uninstall módulo comunitario
Campos relacionales URL 250
Añadiendo, a modelo 74-77 grupos de
Informe.Diseño_externo 317 seguridad
RequireJS Asignando, a usuarios 233-
URL 313 237 creando 233-237
Calendario de recurso 287 Utilizado, para activar características 246-
ReStructuredText (RST) Formato 251
URL 50 Servidor
Modelo reutilizable features Acciones, creando 273-276
los modelos abstractos que RPC llamadas, haciendo
utilizan 89-91 333-336
Inverso proxy Copia de seguridad de
aproximada bases de datos del
mente 354 servidor, restaurando 16
Configurando 357-362 base de datos,
RPC API respaldando arriba 15
Utilizando 307-309 Base de datos, duplicando 13, 14
375
Interfaz de administración de la creando 314,
base de datos, accediendo 315 campos
10 316
Base de datos,
sacando 14 gestor 10
Contraseña maestra, cambiando
11, 12 contraseña maestra,
encuadre 11
Base de datos nueva, creando
12, 13 laborable 17-19
Registros de servidor
Produciendo, para ayudar depurar métodos
153-156
Lado de servidor
onchange Métodos, llamando 141-
143 pruebas de servidor
Corriendo 172, 173
Fragmento
Ofrenda, a usuario 318-322
Fuente
Odoo, instalando de 2-5
Odoo, actualizando de 25-27
Vista concreta
De apertura, por acción 184, 185
Consultas de SQL
que ejecutan 130-
132
SSL
Configurando 357-362
SSL Certificado
358 orden de inicio
Utilizado, para gestor Odoo entornos 9, 10
Subtipos 279
systemd
Configurando, para empezar Odoo 356
sysvinit
Configurando, para empezar Odoo 356, 357
T
t-Tan atributo 316 t-att-
dateCreated 316 t-attf-
atributo de clase 316 t-
attf-* construcción 316
t-atributo de llamada
315 elemento de
plantilla 318 plantillas
Atributos 316
conditionals 316
inline Editando 317, 318 Configurando, para empezar Odoo 356,
modificando 314, 315 357
Pruebas Usuario
Escritura, para client-código de lado 336-339 Errores, informando 99, 100
escritura para módulo, pruebas de unidad de Actuando acción, cambiando 126,
la Pitón utilizaron 127 preferences, configurando 253-
168-171 256 redirigiendo 137
Escritura para módulo, YAML utilizó 164-166 Fragmento, ofrenda 319-323
t-Atributo de opciones del
campo 316 t-foreach elemento V
316 condiciones de tiempo
Automatizó acciones, utilizando 283-287 Vistas
Modelos transitorios 133 Añadiendo 57-61
archivos de traducción Orden de evaluación 204,
importing 266, 267 205 herencia 201-203
Traducciones Entornos virtuales (virtualenv) 5, 6, 368
Aliviando, gettext las herramientas utilizaron
264-266 W
Cuerdas de traducción
Web acceso de caminos
que exportan 261- accesibles, restringiendo
264 300-302
Ventajas de
U web 54 web
UI módulo
Traduciendo 258-260 URL 339
upstart Sitio web.Plantilla de diseño 315-317
376
werkzeug X
URL 295
widgets XML archivos
Añadiendo, para formar Utilizado, para cargar dato 221-224
vista 186 acción de XMLRPC 309
ventana
Añadiendo 180-183 Y
Brujo
Aproximadamente 91, 133 YAML
Y reutilización de código 136 Archivos, utilizados para cargar dato
Escritura, para guiar usuario 228, 229 utilizó, para escribir el
133-136 módulo prueba 164-167
Wkhtmltopdf
Aproximada
mente 5
URL 5
Definicionesde flujo del trabajo
URL 294
Escribe()
Extendiendo 117-120
377