Introdução
Os campos Binary podem não atrair holofotes, mas são ubiquos em qualquer implementação Odoo madura. Sempre que um utilizador anexa um contrato assinado, junta uma ficha técnica de produto ou guarda o logótipo da empresa num registo, existe um campo Binary a gerir esse ficheiro. Saber como esses dados são guardados, para onde vão e quando optar por outro tipo de campo é essencial ao criar formulários personalizados ou estender modelos no Odoo.
Este guia explica o que um campo Binary guarda, como o modo de anexos (attachment) influencia armazenamento e desempenho, como o criar com Odoo Studio ou em Python e exemplos práticos em CRM, RH, Inventário e áreas afins.
O que é o campo Binary no Odoo
No ORM do Odoo, um campo Binary (fields.Binary) guarda dados binários brutos: ficheiros, imagens, PDFs ou qualquer conteúdo que um utilizador suba para um registo. Na interface aparece como um controlo de upload/download: o utilizador envia o ficheiro e, depois, faz o download com um clique.
O detalhe técnico mais relevante é para onde esses bytes vão. Nas versões recentes do Odoo, o comportamento por defeito é usar anexos (attachment). Ou seja, o conteúdo do ficheiro fica na tabela ir.attachment e no filestore do servidor; a coluna do modelo contém apenas uma referência ao anexo. Isso mantém as tabelas principais enxutas e permite ao Odoo gerir ficheiros de forma eficiente.
No Odoo Studio o campo Binary surge como «File» no seletor de campos e desenha-se como um controlo simples de envio e descarga em vistas de formulário. Para imagens existe também fields.Image, uma subclasse com redimensionamento automático e pré-visualização em miniatura — ideal quando o conteúdo é visual. Veremos isso com mais detalhe adiante.
Exemplo de definição do campo num modelo Python:
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_signed_contract = fields.Binary(
string='Signed Contract',
attachment=True,
)
x_signed_contract_filename = fields.Char(
string='Signed Contract Filename',
)
Perceba o campo acompanhante x_signed_contract_filename. É prática comum no Odoo adicionar um campo Char para guardar o nome original do ficheiro. Esse campo _filename permite à interface apresentar o nome correcto quando o utilizador descarrega o ficheiro; sem ele, os downloads aparecem com nomes genéricos.
Como funciona o campo
Quando declara um campo Binary no modelo, o Odoo trata automaticamente da criação da coluna na base de dados durante a instalação ou atualização do módulo. Não é necessário executar SQL manualmente.
Modos de armazenamento
O parâmetro attachment num campo Binary define onde os bytes do ficheiro são guardados:
- attachment=True (recomendado): O conteúdo do ficheiro é colocado em ir.attachment e ligado ao registo pelo nome do modelo e ID. A coluna do modelo mantém só a referência. Esta abordagem mantém as tabelas principais leves e tira partido do filestore do Odoo.
- attachment=False: Os dados base64-encoded são armazenados directamente na coluna do modelo. Isso faz com que as tabelas cresçam muito, tornando consultas mais lentas. Evite este modo para qualquer coisa maior que uma pequena miniatura de imagem.
Formato dos dados
Os campos Binary armazenam e devolvem dados como strings base64. Ao ler via ORM ou API XML-RPC recebe uma string base64; ao escrever deve fornecer também uma string base64.
Na prática, significa codificar antes de escrever e decodificar após ler:
import base64
# Escrita para um campo Binary
with open('document.pdf', 'rb') as f:
encoded = base64.b64encode(f.read()).decode('utf-8')
record.write({'x_signed_contract': encoded})
# Leitura de um campo Binary
raw_bytes = base64.b64decode(record.x_signed_contract)
Atributos importantes do campo
Estes são os atributos mais úteis que pode configurar num campo Binary no Odoo:
- attachment: Booleano. Indica se o ficheiro vai para ir.attachment (True) ou para a coluna do modelo (False). Nas versões recentes o padrão é True.
- string: Etiqueta que aparece na interface.
- required: Torna o campo obrigatório antes de gravar o registo.
- compute: Permite ligar um método Python para calcular dinamicamente o valor, por exemplo gerar um PDF on‑the‑fly.
- store: Com compute, define se o valor calculado é guardado na base de dados.
- groups: Restringe acesso a grupos de utilizadores; importante para documentos sensíveis.
- copy: Controla se o valor é duplicado ao copiar um registo. O comportamento por defeito varia consoante o modo attachment e a versão do Odoo.
A subclasse fields.Image
fields.Image é uma especialização de fields.Binary introduzida no Odoo 13. Acrescenta redimensionamento automático até uma dimensão máxima configurável, uma imagem de pré‑visualização (thumbnail) e uma renderização adequada nas vistas. Para fotos de produto, retratos de parceiros ou logótipos, use fields.Image em vez de Binary — evita uploads desmesurados e melhora a experiência do utilizador.
Como aparece nas vistas
Em formulários, o widget padrão para Binary é um botão de upload/download. Para imagens, aplique o widget image para obter miniaturas. Em vistas de lista, normalmente não mostra o conteúdo binário directamente, porque carregar ficheiros completos por cada linha gera tráfego desnecessário; use um ícone ou um booleano calculado para indicar presença de ficheiro.
Casos de uso práticos
Exemplos práticos em módulos comuns
CRM: Guardar NDAs ou contratos assinados no registo do cliente
Equipes de vendas valorizam ter contratos ou NDAs anexos ao registo do cliente ou lead. Um Binary em res.partner ou crm.lead oferece acesso imediato aos documentos sem sair do Odoo, evitando ferramentas externas para armazenamento básico e mantendo tudo no contexto do processo de venda.
RH: Documentos do colaborador
O departamento de RH precisa de guardar cópias de BI, autorizações de trabalho, contratos assinados e certificados de formação. Um Binary em hr.employee mantém esses documentos sob as regras de acesso do Odoo. Usando groups pode limitar a visualização a gestores de RH, protegendo dados sensíveis e cumprindo requisitos de privacidade.
Inventário: Fichas técnicas e fichas de segurança
Produtos técnicos costumam trazer PDFs de especificações ou fichas de segurança. Um Binary em product.template permite que procurement e armazém acedam à documentação a partir do ficheiro do produto. É uma adaptação muito pedida na indústria e simples de implementar com Studio ou módulos personalizados.
Vendas: Carimbo da empresa ou assinatura autorizada
Algumas empresas precisam que cotações ou confirmações de encomenda impressas incluam um carimbo ou assinatura. Um fields.Image em res.company guarda esse asset visual, que depois é referenciado em relatórios QWeb para estampilhar documentos automaticamente, poupando tempo e reduzindo erros manuais em operações com grande volume.
Contabilidade: Fatura/recibo digital anexado a despesas
Em processos de despesas, anexar o recibo ou fatura digital é prática habitual para reembolsos. O sistema de attachments do Odoo já cobre o caso padrão, mas em modelos personalizados um campo Binary oferece uma forma limpa de guardar a imagem ou PDF no registo e integrá‑lo no fluxo de aprovação sem depender do painel de anexos genérico.
Criar ou personalizar um campo Binary
Três formas de adicionar um campo Binary, consoante as necessidades técnicas e o contexto de implementação.
Usando Odoo Studio (sem código)
Odoo Studio é a ferramenta low‑code integrada. Para adicionar um Binary sem programar:
- Abra o Odoo Studio a partir do menu principal.
- Navegue até ao formulário onde quer o novo campo.
- Arraste um campo «File» do seletor para o formulário.
- Defina a etiqueta e condições de visibilidade nas propriedades.
- Guarde e feche o Studio.
O Studio cria o campo com prefixo x_studio_ e usa attachment mode por padrão. Não é preciso configurar a base de dados manualmente — é a opção mais rápida para utilizadores de negócio que precisam de upload de ficheiros sem envolver programadores.
Usando Python num módulo personalizado
Para desenvolvimentos versionados e portáveis entre ambientes, o método padrão é declarar o campo em Python num módulo. É a abordagem recomendada para personalizações sérias:
from odoo import fields, models
class HrEmployee(models.Model):
_inherit = 'hr.employee'
x_id_document = fields.Binary(
string='ID Document',
attachment=True,
groups='hr.group_hr_user',
)
x_id_document_filename = fields.Char(
string='ID Document Filename',
)
Depois de declarar o campo, inclua‑o na vista de formulário com widget binary e o atributo filename a apontar para o Char acompanhante. Odoo trata da criação da coluna na instalação/upgrade do módulo. Esta abordagem funciona em Odoo.sh e em instalações on‑premise.
Usando a API XML‑RPC
Se cria campos de forma programada, por exemplo em scripts de configuração remota, pode criar campos Binary via XML‑RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_custom_document',
'field_description': 'Custom Document',
'model_id': model_id,
'ttype': 'binary',
'state': 'manual',
}]
)
O parâmetro state: 'manual' indica que o campo foi criado manualmente em vez de por um módulo. Os campos criados pela API usam attachment mode por defeito nas versões actuais. Esta técnica é útil em scripts de automação ou workflows de deployment remoto.
Boas práticas
1. Use sempre attachment=True
Exceto por motivos técnicos muito específicos, utilize attachment mode. Mantém as tabelas compactas, evita consultas lentas e tira partido do filestore do Odoo. Para qualquer ficheiro maior que uma miniatura, attachment=True é praticamente obrigatório; nas versões mais recentes é o comportamento por defeito.
2. Associe sempre um campo Char para o nome do ficheiro
Adicione um campo _filename quando o Binary aparece numa vista. Sem ele, o widget não mostra o nome original e o utilizador recebe ficheiros com nomes genéricos como download. É uma linha de código que melhora substancialmente a experiência do utilizador.
3. Use fields.Image para conteúdo visual
Para fotos de produto, retratos ou logótipos, escolha fields.Image. Limita automaticamente dimensões, gera miniaturas e melhora o desempenho. Escolher o tipo certo para o conteúdo certo é essencial numa modelagem de dados limpa no Odoo.
4. Restringa acesso com groups
Documentos sensíveis — contratos, arquivos de colaboradores, registos financeiros — devem ter restrições via groups. Isso controla quem pode ler/escrever o campo, uma exigência importante para privacidade e auditoria em ambientes regulamentados.
5. Trate a codificação base64 com cuidado no código
Ao ler ou escrever Binary programaticamente, manipule sempre a codificação base64 explicitamente: base64.b64encode(bytes).decode('utf-8') ao escrever e base64.b64decode(valor) ao ler. Não presuma o formato; muitos bugs surgem por não tratar corretamente essa conversão quando se processam ficheiros reais.
Erros comuns a evitar
Perigos de usar attachment=False para ficheiros grandes
Guardar ficheiros directamente na coluna da base de dados pode inchar tabelas PostgreSQL rapidamente. Algumas dezenas de PDFs com attachment=False podem acrescentar centenas de megabytes a uma só tabela, degradando o desempenho. Esta é uma das falhas de configuração mais gravosas que vemos; migrar depois para attachment mode exige scripts personalizados e planeamento cuidadoso.
Esquecer o campo acompanhante do nome do ficheiro
Sem o Char acompanhante, os downloads aparecem com nomes genéricos — um pequeno mas irritante problema que dá aspecto de solução inacabada. Acrescentar o campo é rápido e deve ser sempre parte da definição quando o campo Binary fica visível a utilizadores.
Confundir Binary com Image
Usar Binary para imagens perde o redimensionamento e as miniaturas que fields.Image fornece. Isso pode permitir uploads demasiado grandes que afectam a velocidade e o armazenamento. Por outro lado, usar fields.Image para PDFs ou outros tipos não‑imagem causa erros porque o Odoo tenta processar conteúdos como imagem. A regra é simples: combine o tipo de campo com o tipo esperado de conteúdo.
Incluir Binary directamente em vistas de lista
Mostrar um Binary numa lista força o Odoo a carregar o conteúdo completo para cada linha visível — para cinquenta registos, pode ser megabytes de dados só para exibir a página. Em listas, em vez de mostrar o Binary, crie um booleano calculado ou um ícone que sinalize a existência do ficheiro para evitar problemas de desempenho.
Não verificar False antes de processar em código
Um campo Binary sem valor devolve False em Python, não string vazia nem bytes vazios. Tentar decodificar sem verificar causa um TypeError. Proteja o código: if record.x_document: data = base64.b64decode(record.x_document). Isto aplica‑se em métodos compute, ações de servidor e qualquer lógica que processe Binary condicionalmente.
Conclusão
O campo Binary é simples mas essencial no modelo de dados do Odoo. Ele integra armazenamento de ficheiros com a interface, o sistema de attachments e o controlo de acesso da plataforma.
Há hábitos-chave a adoptar: use attachment mode, associe sempre um campo Char para o nome do ficheiro, opte por fields.Image para imagens, restrinja acesso quando necessário e trate a codificação base64 com rigor. Essas práticas evitam os problemas mais comuns antes que apareçam em produção.
Quer esteja a adicionar um campo via Odoo Studio, a desenvolver um módulo em Python ou a gerir criação de campos via ORM/API, acertar nos Binary desde o início resulta numa implementação Odoo mais limpa e fiável.
Na Dasolo ajudamos empresas a implementar, personalizar e otimizar Odoo em todas as áreas. Se precisa de apoio para modelagem de dados, fluxos de gestão de ficheiros ou desenvolvimento de módulos, a nossa equipa está disponível para colaborar. Contacte‑nos e falemos sobre o seu projeto Odoo.