Introducción
Cada vez que alguien marca la prioridad de un lead, elige un método de pago o cambia el estado de un producto entre activo y archivado en Odoo, probablemente está interactuando con un campo tipo Selection. Este tipo de campo es uno de los más versátiles dentro del ecosistema Odoo y merece atención si quieres modelar datos sólidos y previsibles.
A diferencia de un campo de texto libre, donde el usuario puede escribir cualquier cosa, un Selection limita las entradas a un conjunto definido de opciones. Esa restricción es su ventaja principal: mantiene la uniformidad de los datos, facilita búsquedas y filtros precisos y evita errores tipográficos o variantes que, con el tiempo, rompen informes y agregaciones.
Esta guía explica qué guarda el campo, cómo se muestra en la interfaz y las maneras de crearlo o modificarlo (desde Odoo Studio, módulos en Python o la API XML-RPC). También incluye ejemplos reales de uso en procesos de negocio y una lista de fallos comunes que conviene evitar.
¿Qué es un campo Selection en Odoo?
En el ORM de Odoo, un campo Selection almacena en la base de datos una cadena (string) elegida entre un conjunto fijo de opciones. Cada opción se define como un par clave-etiqueta: la clave es lo que queda persistido y la etiqueta es lo que ve el usuario en pantalla.
Para entenderlo mejor, imagina un campo de prioridad que ofrece varias alternativas predefinidas.
priority = fields.Selection([
('0', 'Normal'),
('1', 'Low'),
('2', 'High'),
('3', 'Very High'),
], string='Priority', default='0')
En ese ejemplo, '0', '1', '2' y '3' son las claves almacenadas; las etiquetas Normal, Low, High y Very High son las que muestra la interfaz. Esa separación es clave: te permite cambiar textos visibles sin romper los registros ya existentes.
En la interfaz, un Selection se muestra normalmente como un desplegable en las vistas de formulario; en las vistas de listado aparece la etiqueta legible. Si aplicas el widget badge, cada opción se pinta como una etiqueta de color, útil para identificar estados en vistas densas.
Dentro de Odoo Studio este tipo aparece como Selection. Si lo creas desde Studio, Odoo le antepone el prefijo x_studio_; si lo defines por código o mediante la API, decides el nombre técnico tú mismo.
Cómo funciona el campo
Técnicamente, en PostgreSQL el Selection se guarda en una columna VARCHAR. La base de datos almacena únicamente la clave, nunca la etiqueta. Por eso, al construir dominios o acciones en el servidor debes usar la clave, no el texto visible.
Por ejemplo, para buscar todos los leads con alta prioridad usarías [('priority', '=', '2')] y no [('priority', '=', 'High')].
Atributos clave del campo
Estos son los parámetros más relevantes de un campo Selection en Odoo:
- selection: La lista de tuplas
(clave, etiqueta)que define las opciones disponibles. También puede ser el nombre de un método (como string) que devuelva esa lista dinámicamente. - default: La clave que se aplica cuando no se ha establecido ningún valor. Si no se especifica, el campo queda vacío.
- required: Obliga al usuario a elegir una opción antes de guardar. Junto con un valor por defecto es habitual para campos de estado.
- selection_add: Se usa en herencia de módulos para añadir opciones a un Selection existente sin redefinir toda la lista; es la forma correcta de extender campos nativos.
- ondelete: Complementa a
selection_addy define el comportamiento sobre los registros que tienen una opción eliminada cuando se desinstala el módulo que la añadió.
Listas estáticas frente a dinámicas
Por defecto, las opciones se declaran de forma estática. Pero puedes pasar el nombre de un método a selection; Odoo lo ejecutará en tiempo de ejecución y así puedes devolver distintas listas según el usuario, la compañía o cualquier contexto.
contract_type = fields.Selection(
selection='_get_contract_types',
string='Contract Type'
)
def _get_contract_types(self):
if self.env.user.has_group('hr.group_hr_manager'):
return [('permanent', 'Permanent'), ('fixed', 'Fixed Term'), ('interim', 'Interim')]
return [('permanent', 'Permanent'), ('fixed', 'Fixed Term')]
Cómo se muestra en las vistas
En un formulario, el Selection se renderiza como un desplegable estándar. Con widget="badge" aparece como una etiqueta de color; widget="radio" lo transforma en botones radio inline, conveniente cuando hay pocas opciones y quieres que todas sean visibles simultáneamente.
Interacción con el ORM de Odoo
Leer y escribir campos Selection desde el ORM es directo: asignas la clave y Odoo gestiona la presentación. Si consultas la definición con fields_get vía XML-RPC, el atributo selection devuelve la lista completa [key, label], útil para construir la lógica de presentación en herramientas externas.
Casos de uso en la práctica
El Selection está presente en casi todos los módulos estándar de Odoo. A continuación tienes cinco ejemplos concretos en procesos empresariales habituales.
CRM: prioridad de lead y tipo de etapa
La prioridad en los leads es un Selection con varios niveles. Los equipos comerciales lo usan para priorizar esfuerzos, colorear tarjetas en Kanban y disparar acciones automáticas cuando una oportunidad sube de nivel. Ajustar correctamente la distribución de prioridades suele ser una de las primeras mejoras de calidad de datos tras el arranque del CRM.
Ventas: política de facturación y condiciones de pago
El campo invoice_policy en productos define si la facturación se basa en cantidades pedidas o entregadas; una sola opción que condiciona todo el flujo de cobros. De forma similar, los contratos de suscripción usan un Selection para distinguir entre facturación anticipada o posterior. Son ejemplos de Selection que afectan directamente a procesos financieros.
Inventario: estados de calidad de producto y lote
En fabricación y control de calidad, los Selection rastrean estados de lotes, números de serie u órdenes de reparación. El estado de una orden de reparación transita por valores como borrador, confirmado, en reparación, listo y terminado; cada avance puede desencadenar emails, movimientos de stock o asientos contables. El Selection actúa como el punto de control del flujo.
Contabilidad: método de pago y tipo de diario
El tipo de diario en contabilidad es un Selection que distingue diarios de ventas, compras, efectivo o bancos. Odoo usa ese valor para aplicar la lógica de contabilización correcta, decidir qué cuentas están disponibles y limitar operaciones según el tipo de diario. Es un buen ejemplo de Selection que gobierna reglas de negocio, no solo etiquetas.
RRHH: tipo de contrato y estado laboral
En Recursos Humanos se usan Selection para registrar tipos de empleo, estados de contrato o estados de solicitudes de permiso. El estado de contrato puede pasar de nuevo a abierto, a expirado o cancelado; las automatizaciones pueden alertar al responsable antes de la expiración, lanzar checklists de incorporación o adaptar reglas de nómina según el tipo de empleo.
Crear o personalizar un Selection
Formas de añadir un Selection a un modelo
Hay tres vías principales para agregar un Selection a un modelo Odoo, según necesites control de versiones o aplicar cambios de forma programática.
Con Odoo Studio (sin código)
- Odoo Studio es la herramienta low-code incorporada para añadir campos sin tocar Python. Para crear un Selection con Studio:
- Abre Odoo Studio desde el menú principal.
- Ve al formulario donde quieres añadir el campo.
- Arrastra un campo Selection desde la barra lateral al formulario.
- Introduce las opciones en el panel de propiedades, escribiendo la etiqueta de cada opción.
- Opcionalmente define un valor por defecto y marca el campo como obligatorio.
Guarda y cierra Studio.
Studio crea claves automáticamente y guarda la etiqueta que hayas puesto. El campo recibe el prefijo x_studio_ y se incorpora al formulario: es la vía más rápida durante workshops o sesiones de análisis con clientes.
Con Python en un módulo personalizado
Los desarrolladores definen Selection en ficheros Python dentro de un módulo. Es el enfoque recomendado cuando la personalización debe controlarse en un repositorio y desplegarse en varios entornos:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_delivery_slot = fields.Selection([
('morning', 'Morning (8h - 12h)'),
('afternoon', 'Afternoon (13h - 17h)'),
('evening', 'Evening (18h - 20h)'),
], string='Delivery Slot', default='morning')
Tras declarar el campo debes añadirlo en la vista XML correspondiente. Odoo crea la columna en la base de datos al instalar o actualizar el módulo.
Si vas a añadir nuevas opciones a un campo nativo, usa selection_add en lugar de redefinirlo completamente:
class SaleOrder(models.Model):
_inherit = 'sale.order'
state = fields.Selection(
selection_add=[('custom_approval', 'Pending Approval')],
ondelete={'custom_approval': 'set default'}
)
Mediante la API XML-RPC
Si gestionas personalizaciones de forma programática (por ejemplo en un pipeline de despliegue), puedes crear Selection vía XML-RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_contract_category',
'field_description': 'Contract Category',
'model_id': model_id,
'ttype': 'selection',
'selection': "[('standard', 'Standard'), ('premium', 'Premium'), ('custom', 'Custom')]",
'state': 'manual',
}]
)
Buenas prácticas
Cuando se crea un Selection vía API, el parámetro selection se envía como la representación en string de la lista Python. El valor state: 'manual' indica que el campo fue creado manualmente (apropiado para Studio o la API). Muchas consultoras usan este método para automatizar configuraciones en clientes.
1. Usa claves significativas y estables
La clave es lo que queda en la base de datos y lo que deben usar dominios, acciones automáticas y lógica del servidor. Escoge claves descriptivas que no necesites cambiar: cadenas cortas en minúsculas como 'draft', 'confirmed', 'cancelled' funcionan bien. Evita claves numéricas salvo que la secuencia tenga sentido, porque dificultan la lectura del código con el tiempo.
2. Mantén la lista breve y completa
Si un Selection supera las ocho–diez opciones suele ser señal de que el campo está haciendo demasiado. Si la lista crece con frecuencia, valora usar una relación Many2one a un modelo de configuración: permite que los usuarios gestionen las opciones desde la interfaz sin tocar código.
3. Pon siempre un default en campos obligatorios
Si el campo es requerido, define un valor por defecto sensato. Así evitas errores de validación al crear registros por importación, API o procesos automáticos donde no hay un usuario interactuando. El default debe representar el estado más habitual o el menos comprometedor del flujo.
4. Usa selection_add para extender campos nativos
Al añadir opciones a un campo existente desde un módulo propio, emplea selection_add en vez de redefinir el campo entero; es más seguro y compatible con otras extensiones. Acompáñalo siempre con ondelete para gestionar la desinstalación del módulo.
5. Emplea el widget badge para mayor visibilidad
Errores habituales
En listas y Kanban, por defecto el Selection muestra texto. Añadir widget="badge" en la vista XML transforma cada valor en una etiqueta coloreada, haciéndolo mucho más fácil de escanear. Es especialmente útil en campos de estado que requieren identificación rápida.
Cambiar una clave rompe los datos existentes
La etiqueta visible puede modificarse con seguridad porque la base de datos solo guarda la clave. En cambio, si cambias la clave después de que existan registros con ese valor, esos registros quedarán con un valor inválido u oculto y los filtros o automatizaciones dejarán de funcionar sin avisar. Si debes renombrar una clave, realiza previamente una migración de datos para actualizar todos los registros afectados.
Eliminar una opción deja registros huérfanos
Quitar una opción mientras todavía hay registros con esa clave deja esos registros con valores rotos o vacíos. Antes de eliminar una opción busca los registros que la usan y actualízalos o archívalos. Es un problema frecuente en limpiezas de datos cuando las opciones se diseñaron sin el análisis adecuado.
Filtrar por la etiqueta en lugar de por la clave
Un error común, sobre todo entre usuarios no técnicos que crean reglas en la interfaz, es construir dominios usando la etiqueta visible en vez de la clave almacenada. Ese filtro normalmente devuelve cero resultados sin generar un error, lo que complica su diagnóstico. Revisa la definición del campo para confirmar la correspondencia clave-etiqueta antes de crear filtros.
Usar Selection donde convendría un Many2one
Si las opciones cambian a menudo, los usuarios deben gestionarlas sin desarrolladores o las opciones tienen atributos adicionales (color, secuencia, cuenta asociada), un Many2one a un modelo de configuración es más apropiado. Los Selection son ideales para listas estables y gestionadas por desarrolladores; para listas dinámicas, Many2one es más sostenible.
No gestionar el valor vacío en la lógica del servidor
Conclusión
Un Selection no obligatorio puede quedar con valor False si no se ha seleccionado nada. Si tu código en Python o tus acciones automáticas comparan directamente con una cadena sin comprobar False, producirás comportamientos inesperados o errores. Maneja explícitamente el caso vacío en acciones servidor y campos computados que dependan del Selection.
El campo Selection parece simple, pero tiene matices importantes: distinguir entre clave y etiqueta, saber cuándo usar selection_add en vez de redefinir, o reconocer que un Many2one puede ser mejor son decisiones que marcan la diferencia entre una implantación de Odoo robusta y otra que dará problemas pasados los meses.
Tanto si añades un tipo de contrato desde Studio, defines franjas de entrega en un módulo Python o creas estados de calidad vía API, los patrones que has visto en esta guía te ayudarán a elegir la solución adecuada para cada caso.
En el modelo de datos de Odoo, el Selection es una herramienta esencial para garantizar la calidad de los datos desde el origen. Usado correctamente mantiene registros ordenados, informes fiables y automatizaciones estables. En Dasolo ayudamos a empresas a implantar, personalizar y optimizar Odoo en todas las áreas. Si necesitas diseñar un modelo de datos limpio, añadir campos personalizados o desarrollar un módulo a medida, te acompañamos en el proceso. Contáctanos