Introducción
Los campos binarios no son glamorosos, pero están en todas partes en una implementación real de Odoo. Cada vez que un usuario sube un contrato firmado, adjunta una hoja de datos de producto o almacena un logotipo de empresa en un registro, hay un campo Binario trabajando tras bambalinas. Entender cómo almacena datos, dónde termina esos datos y cuándo usar un tipo de campo diferente hace una gran diferencia al construir formularios personalizados o extender modelos de Odoo.
Esta guía cubre lo que almacena el campo Binario, cómo el modo de adjunto afecta el almacenamiento y el rendimiento, cómo crearlo y personalizarlo utilizando Odoo Studio o Python, y casos de uso empresarial prácticos en CRM, RRHH, Inventario y más.
¿Qué es el campo Binario en Odoo?
En el ORM de Odoo, el campo Binario (fields.Binary) almacena datos binarios en bruto: archivos, documentos, imágenes o cualquier contenido que un usuario suba a un registro. Desde la perspectiva del usuario, aparece como un botón de carga de archivos en las vistas de formulario. Una vez que se adjunta un archivo, el mismo botón permite a los usuarios descargarlo con un solo clic.
El detalle técnico más importante es dónde terminan realmente esos datos. Por defecto, en las versiones modernas de Odoo, los campos Binarios utilizan el modo de adjunto. Esto significa que el contenido del archivo se almacena en la tabla ir.attachment y en el almacenamiento de archivos del servidor, no directamente dentro de la columna del modelo. La columna del modelo solo contiene un ID de referencia que apunta al registro de adjunto. Este enfoque mantiene tus tablas de base de datos principales delgadas y permite a Odoo gestionar archivos de manera eficiente.
En Odoo Studio, el campo Binario está etiquetado como Archivo en el selector de campos. Se presenta como un control simple de carga y descarga en las vistas de formulario. Para contenido de imagen específicamente, Odoo también proporciona un tipo dedicado fields.Image que añade redimensionamiento automático y vista previa en miniatura. Cubriremos eso en las secciones relevantes a continuación.
Así es como se ve un campo Binario en una definición de modelo de Python:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_signed_contract = fields.Binary(
string='Contrato Firmado',
attachment=True,
)
x_signed_contract_filename = fields.Char(
string='Nombre del Archivo del Contrato Firmado',
)
Nota el campo Char compañero x_signed_contract_filename. Emparejar un campo Binario con un campo Char para el nombre del archivo es un patrón de desarrollo estándar en Odoo. Odoo utiliza el campo _filename para recordar y mostrar el nombre original del archivo en la interfaz. Sin él, los archivos descargados pueden recibir un nombre genérico.
Cómo funciona el campo
Cuando defines un campo Binario en el modelo de datos de Odoo, el marco maneja la creación de la columna automáticamente al instalar o actualizar el módulo. No se necesita SQL manual de tu parte.
Modos de Almacenamiento
El parámetro attachment en un campo Binario controla dónde se almacenan realmente los bytes del archivo:
- attachment=True (recomendado): El contenido del archivo se almacena en
ir.attachment, vinculado al registro por nombre de modelo e ID de registro. La columna del modelo solo contiene un ID de referencia. Esto mantiene las tablas del modelo pequeñas y aprovecha el sistema de almacenamiento de archivos de Odoo. - attachment=False: Los datos en bruto codificados en base64 se almacenan directamente dentro de la columna de la base de datos del modelo. Esto hace que las tablas crezcan muy grandes, ralentizando las consultas en todo el modelo. Evita este modo para cualquier cosa más grande que una pequeña miniatura de imagen.
Formato de Datos
Los campos Binarios almacenan y devuelven datos como bytes codificados en base64. Cuando lees un campo Binario a través del ORM de Odoo o la API XML-RPC, recibes una cadena en base64. Cuando escribes en él, también debes proporcionar una cadena codificada en base64.
En la práctica, esto significa codificar antes de escribir y decodificar después de leer:
import base64
# Escribiendo un archivo en un campo Binario
with open('document.pdf', 'rb') as f:
encoded = base64.b64encode(f.read()).decode('utf-8')
record.write({'x_signed_contract': encoded})
# Leyendo un archivo de un campo Binario
raw_bytes = base64.b64decode(record.x_signed_contract)
Atributos del Campo Clave
Estos son los atributos más importantes que puedes configurar en un campo Binario en el marco de Odoo:
- attachment: Booleano. Si se debe almacenar en
ir.attachment(Verdadero) o directamente en la columna (Falso). Predeterminado: Verdadero en versiones recientes de Odoo. - string: Etiqueta de visualización mostrada en la interfaz.
- required: Hace que el campo sea obligatorio antes de guardar el registro.
- compute: Vincula un método de Python para calcular el valor del campo dinámicamente, por ejemplo, generando un PDF sobre la marcha como un campo calculado de Odoo.
- store: Cuando se usa con
compute, guarda el valor calculado en la base de datos. - groups: Restringe el acceso al campo a grupos de usuarios específicos de Odoo. Importante para documentos sensibles.
- copy: Controla si el valor se duplica cuando se copia un registro. Los valores predeterminados varían según el modo de adjunto y la versión de Odoo.
La Subclase fields.Image
fields.Image es una subclase especializada de fields.Binary introducida en Odoo 13. Agrega redimensionamiento automático de imágenes a una dimensión máxima configurable, un tamaño de vista previa opcional para miniaturas y renderiza una vista previa de imagen adecuada en las vistas de formulario. Para almacenar imágenes de productos, fotos de socios, logotipos de empresas o cualquier contenido visual, utiliza fields.Image en lugar de un campo Binario simple. Previene cargas excesivamente grandes y proporciona una experiencia de usuario mucho mejor para los datos de imagen.
Cómo Aparece en las Vistas
En las vistas de formulario, el widget predeterminado para un campo Binario es un botón de carga y descarga. Para contenido de imagen, aplica el widget image para obtener una vista previa en miniatura en su lugar. En las vistas de lista, los campos Binarios generalmente no se muestran directamente porque cargar el contenido completo del archivo para cada fila visible crea una transferencia de datos innecesaria. El enfoque estándar es mostrar un indicador booleano o un ícono en las vistas de lista para señalar si un archivo está adjunto.
Casos de uso empresarial
El campo Binario aparece en muchos módulos de Odoo en implementaciones reales. Aquí hay cinco ejemplos prácticos de flujos de trabajo comerciales comunes.
CRM: Almacenamiento de NDAs o Contratos Firmados en Registros de Clientes
Muchas empresas necesitan adjuntar un documento firmado directamente a un registro de cliente o prospecto en Odoo CRM. Un campo Binario en res.partner o crm.lead proporciona a los equipos de ventas acceso con un clic al contrato relevante sin salir de la interfaz de Odoo. Esto elimina la necesidad de una herramienta de gestión documental separada para el almacenamiento básico de archivos, y mantiene la información exactamente donde el equipo espera encontrarla durante el proceso de ventas.
RRHH: Almacenamiento de Documentos de Empleados
Los departamentos de RRHH necesitan regularmente almacenar copias de documentos de identificación de empleados, permisos de trabajo, contratos de empleo firmados o certificados de formación. Un campo Binario en hr.employee almacena estos archivos de forma segura dentro del sistema de control de acceso de Odoo. Usando el atributo groups, puedes restringir la visibilidad para que solo los gerentes de RRHH puedan ver documentos sensibles, mientras que otros gerentes ven el formulario sin acceder a los archivos reales. Esta es una solicitud común de personalización de Odoo en empresas con estrictos requisitos de privacidad de datos.
Inventario: Hojas de Especificaciones de Productos y Datos de Seguridad
Los productos técnicos a menudo vienen con hojas de especificaciones en PDF, hojas de datos de seguridad o certificados de calidad del fabricante. Un campo Binario en product.template permite a los equipos de adquisiciones y al personal del almacén acceder a la documentación correcta directamente desde el registro del producto en Odoo. Esta es una de las adiciones de personalización de Odoo más solicitadas en empresas de fabricación y distribución, y es fácil de implementar ya sea con Odoo Studio o un módulo personalizado de Python.
Ventas: Imagen del Sello de la Empresa o Firma Autorizada
Algunos contextos empresariales requieren un sello de la empresa o una firma autorizada en cotizaciones impresas o confirmaciones de pedidos. Un campo fields.Image en res.company almacena este activo visual, que luego puede ser referenciado en una plantilla de informe QWeb. Esto permite que los documentos impresos incluyan automáticamente el sello sin ningún manejo manual por documento, ahorrando tiempo en operaciones de ventas de alto volumen y reduciendo el riesgo de enviar cotizaciones no firmadas por accidente.
Contabilidad: Adjunto de Recibo Escaneado en Registros de Gastos
Los flujos de trabajo de gestión de gastos suelen requerir adjuntar un recibo escaneado o una factura a cada registro de gasto como prueba para el reembolso. Para los gastos estándar de Odoo, el sistema de adjuntos maneja esto de forma nativa. Pero en modelos de gastos personalizados, flujos de trabajo de facturas de proveedores o integraciones de terceros, un campo Binario proporciona una forma limpia de almacenar la imagen del recibo o el PDF directamente en el registro e incluirlo en la lógica de enrutamiento de aprobación sin depender del panel de adjuntos genérico.
Creando o personalizando el campo Binario
Hay tres formas principales de agregar un campo Binario a un modelo de Odoo, dependiendo de tu contexto técnico y de cuánto control necesites.
Usando Odoo Studio (Sin Código)
Odoo Studio es la herramienta de personalización de bajo código incorporada. Para agregar un campo Binario sin escribir ningún código:
- Abre Odoo Studio desde el menú principal.
- Navega hasta el formulario donde deseas el campo.
- Arrastra un campo Archivo desde el selector de campos al formulario.
- Establece la etiqueta y cualquier condición de visibilidad opcional en el panel de propiedades.
- Guarda y cierra Studio.
Studio crea el campo con un prefijo x_studio_ y utiliza automáticamente el modo de adjunto. No se necesita configuración de base de datos de tu parte. Este es uno de los campos de Odoo Studio más accesibles para los usuarios de negocios que necesitan capacidad de carga de archivos en sus formularios sin la intervención de un desarrollador.
Usando Python en un Módulo Personalizado
Para el desarrollo de Odoo que necesita ser controlado por versiones y desplegado en múltiples entornos, el enfoque estándar es definir campos Binarios directamente en Python. Este es el enfoque recomendado en cualquier guía de desarrollador de Odoo para trabajos serios de personalización de Odoo:
from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
x_id_document = fields.Binary(
string='Documento de Identidad',
attachment=True,
groups='hr.group_hr_user',
)
x_id_document_filename = fields.Char(
string='Nombre del Archivo del Documento de Identidad',
)
Después de agregar el campo al modelo, inclúyalo en la vista de formulario XML con el widget binary y el atributo filename apuntando al campo Char compañero. Odoo maneja automáticamente la columna de la base de datos al instalar o actualizar el módulo. Este enfoque funciona de manera limpia en todos los tipos de implementación de Odoo, incluyendo Odoo.sh y las instalaciones locales.
Uso de la API XML-RPC
Si está gestionando la creación de campos de Odoo programáticamente, por ejemplo, a través de un script de configuración remoto o un cuaderno de implementación, puede crear campos Binarios a través de la API XML-RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_custom_document',
'field_description': 'Documento Personalizado',
'model_id': model_id,
'ttype': 'binary',
'state': 'manual',
}]
)
El valor state: manual le indica a Odoo que este campo fue creado manualmente en lugar de ser instalado por un módulo. Los campos creados a través de la API utilizan el modo de adjunto por defecto en las versiones actuales de Odoo. Este es el enfoque utilizado en scripts de configuración automatizados de Odoo y flujos de trabajo de implementación remota.
Mejores prácticas
1. Siempre use attachment=True
A menos que tenga una razón técnica muy específica para almacenar el contenido del archivo directamente en la columna de la base de datos, use el modo de adjunto. Mantiene pequeñas las tablas del modelo, previene consultas lentas y permite a Odoo gestionar archivos a través de su sistema de almacenamiento de archivos integrado. Este también es el comportamiento predeterminado en versiones recientes, por lo que simplemente omitir el parámetro attachment es suficiente en la mayoría de los casos. Para cualquier archivo más grande que un pequeño thumbnail, el modo de adjunto no es opcional.
2. Empareje campos Binarios con un campo Char de nombre de archivo
Siempre agregue un campo Char compañero _filename junto a cualquier campo Binario utilizado en una vista de formulario. Sin él, el widget de carga de archivos no puede mostrar o restaurar el nombre de archivo original, y los usuarios que descargan el archivo terminan con un nombre genérico como download. Esta pequeña adición toma una línea de código y hace una diferencia notable en la experiencia del usuario del formulario.
3. Use fields.Image para contenido visual
Si está almacenando fotos de productos, retratos de socios, logotipos de empresas o cualquier otra imagen, use fields.Image en lugar de un campo Binario simple. Limita automáticamente el tamaño de carga a las dimensiones máximas configuradas, renderiza una miniatura en la interfaz e incluye un campo separado para la imagen de vista previa redimensionada. Usar el tipo de campo correcto para el contenido correcto es un principio fundamental en el diseño limpio del modelo de datos de Odoo.
4. Restringir el acceso con el parámetro groups
Los campos binarios que almacenan documentos sensibles como archivos de empleados, contratos firmados o registros financieros deben definir restricciones de acceso utilizando el parámetro groups. Esto limita quién puede leer o escribir en el campo, lo cual es importante tanto para la privacidad de los datos como para los requisitos de auditoría en entornos regulados.
5. Manejar la codificación base64 con cuidado en el código
Al leer o escribir campos binarios programáticamente, siempre maneja la codificación base64 de manera explícita. Usa base64.b64encode(file_bytes).decode('utf-8') para convertir bytes antes de escribir, y base64.b64decode(field_value) para convertir de nuevo a bytes después de leer. No asumas que los datos ya están en el formato que necesitas. Esta es una fuente común de errores en las integraciones de Odoo ORM que solo aparecen cuando se procesan archivos reales.
Errores comunes
Establecer attachment=False para archivos grandes
Almacenar el contenido de archivos directamente en una columna de base de datos puede inflar significativamente tus tablas de PostgreSQL. Unas pocas docenas de documentos PDF almacenados con attachment=False pueden añadir cientos de megabytes a una sola tabla de modelo, ralentizando cada consulta en ese modelo. Este es uno de los errores de configuración más impactantes en la gestión de bases de datos de Odoo. Una vez que los datos se almacenan de esta manera y la tabla crece, migrar al modo de adjunto requiere un script personalizado y una planificación cuidadosa.
Olvidar el campo compañero del nombre de archivo
Sin un campo Char emparejado para el nombre de archivo, los usuarios que descargan un archivo de un campo binario a menudo obtienen un nombre de archivo genérico. Este es un problema pequeño pero persistente que hace que la implementación se sienta incompleta. Agregar el campo compañero toma menos de un minuto y debería ser parte de cualquier definición de campo binario que aparezca en una vista de formulario orientada al usuario.
Confundir campos Binarios e Imágenes
Usar un campo binario simple para contenido de imagen pierde el redimensionamiento automático y la representación en miniatura que proporciona fields.Image. Los usuarios pueden subir archivos de imagen muy grandes que ralentizan la carga de formularios y consumen espacio de almacenamiento innecesario. Por otro lado, usar fields.Image para archivos no de imagen como PDFs causa errores porque Odoo intenta procesar el contenido como una imagen. La regla es simple: empareja el tipo de campo con el tipo de contenido esperado.
Incluir campos Binarios directamente en vistas de lista
Agregar un campo binario a una vista de lista hace que Odoo cargue el contenido completo del archivo para cada fila visible. Para una lista con cincuenta registros, esto puede significar transferir megabytes de datos solo para renderizar la página. Si necesitas indicar la presencia de un archivo en una vista de lista, usa un campo booleano computado o un botón de icono en lugar del campo binario directamente. Este es un problema común de rendimiento en implementaciones de Odoo que solo se vuelve visible con volúmenes de datos reales.
No comprobar si es False antes de procesar en el código
Un campo Binario sin un valor devuelve False en Python, no una cadena vacía ni bytes vacíos. Si intentas decodificar un valor de campo Binario sin comprobar primero si es False, obtienes un TypeError que hace que el método se bloquee. Siempre protege con: if record.x_document: data = base64.b64decode(record.x_document). Esto es importante en métodos de cálculo, acciones del servidor y cualquier código que procese valores Binarios de manera condicional.
Conclusión
El campo Binario es una parte sencilla pero importante del modelo de datos de Odoo. Maneja el almacenamiento de archivos y documentos de una manera que se integra de forma natural con la interfaz de Odoo, su sistema de adjuntos y su marco de control de acceso.
Los principales hábitos a desarrollar: siempre usar el modo de adjunto, emparejar campos Binarios con un campo Char para el nombre de archivo, elegir fields.Image para contenido visual, restringir el acceso a documentos sensibles y manejar la codificación base64 con cuidado en el código personalizado. Estas prácticas previenen los problemas más comunes antes de que tengan la oportunidad de surgir en producción.
Ya sea que estés añadiendo un campo de carga de archivos a través de Odoo Studio, construyendo un módulo personalizado en Python, o gestionando la creación de campos a través del ORM de Odoo o la API XML-RPC, hacer bien los campos Binarios desde el principio conduce a una implementación de Odoo más limpia y confiable en general.
En Dasolo, ayudamos a las empresas a implementar, personalizar y optimizar Odoo en todos los departamentos. Ya sea que necesites ayuda para diseñar un modelo de datos con los tipos de campo correctos, construir flujos de trabajo personalizados de gestión de archivos, o desarrollar un módulo completo de Odoo, nuestro equipo está aquí para apoyarte. Contáctanos y hablemos sobre tu proyecto de Odoo.