Introdução
O campo Many2One é um dos blocos de construção fundamentais do modelo de dados do Odoo. Sempre que você vincula uma ordem de venda a um cliente, atribui um produto a uma categoria ou conecta uma tarefa a um projeto, você está trabalhando com uma relação Many2One. É o tipo de campo relacional mais comum no Odoo, e entender como ele funciona é essencial para qualquer pessoa que esteja fazendo desenvolvimento ou personalização séria no Odoo.
Do ponto de vista empresarial, os campos Many2One são o que conferem ao Odoo sua coerência como um sistema integrado. Sem eles, cada módulo seria uma ilha. Com eles, os dados fluem naturalmente de um registro para outro, e os usuários podem navegar entre documentos relacionados sem nunca pensar na estrutura do banco de dados.
Este guia cobre o que o campo Many2One armazena, como ele se comporta no ORM do Odoo e na interface, como criá-lo e configurá-lo usando o Odoo Studio ou Python, e casos de uso reais de CRM, Vendas, Inventário e Contabilidade.
O que é o campo Many2One no Odoo
No ORM do Odoo, um campo Many2One cria um link de um registro para exatamente um registro em outro modelo. O nome descreve a relação do ponto de vista do modelo atual: muitos registros aqui podem apontar para um registro ali. Por exemplo, muitas ordens de venda podem apontar para um cliente, e muitos produtos podem pertencer a uma categoria de produto.
A nível de base de dados, um campo Many2One armazena uma chave estrangeira na tabela atual. Se uma ordem de venda estiver ligada ao ID do cliente 42, a coluna partner_id na tabela sale_order contém o inteiro 42. Odoo trata automaticamente da junção e da recuperação do nome do registo relacionado.
Na interface do utilizador, um campo Many2One aparece como um menu suspenso ou um campo de entrada tipo autocomplete. Os utilizadores podem começar a digitar um nome, e o Odoo filtra os registos correspondentes em tempo real. Selecionar um define o link. O campo exibe o nome do registo ligado, não o seu ID interno. Isso torna-o um dos tipos de campo mais naturais do ponto de vista da experiência do utilizador.
Aqui está como se apresenta numa definição de modelo Python:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_account_manager_id = fields.Many2One(
comodel_name='res.users',
string='Account Manager',
ondelete='set null',
)
O parâmetro comodel_name é o nome técnico do modelo ao qual está a ligar-se. O parâmetro ondelete controla o que acontece ao registo atual se o registo ligado for eliminado. As três opções são cascade (eliminar o registo atual também), set null (limpar o link) e restrict (bloquear a eliminação se algum registo apontar para ele).
No Odoo Studio, o campo Many2One aparece sob o rótulo Many2One no seletor de campos. Quando adiciona um através do Studio, escolhe o modelo de destino a partir de uma lista, e o Studio trata da criação do campo. Isso torna-o um dos campos mais acessíveis do Odoo Studio para configurar relacionamentos sem escrever código.
Como o campo funciona
Quando lê um campo Many2One através do Odoo ORM, obtém um conjunto de registos contendo o registo ligado. Se o campo estiver vazio, obtém um conjunto de registos vazio. Em Python, pode aceder ao registo relacionado diretamente e navegar pelos seus campos usando a notação de ponto:
order = self.env['sale.order'].browse(1)
customer_name = order.partner_id.name
customer_city = order.partner_id.city
Esta navegação encadeada é um dos aspectos mais convenientes do framework Odoo. Não precisa de escrever junções explícitas ou consultas separadas. O ORM trata do trabalho de base de dados em segundo plano.
Ao ler através da API XML-RPC, um campo Many2One retorna uma lista com dois elementos: o ID inteiro do registo ligado e o seu nome de exibição. Por exemplo, [42, "Acme Corp"]. Se o campo estiver vazio, retorna False. Isso é importante saber ao processar respostas da API nos seus scripts.
Atributos Chave do Campo
Estas são as propriedades mais importantes que pode configurar num campo Many2One no framework Odoo:
- comodel_name: O nome técnico do modelo alvo. Este é o único parâmetro obrigatório.
- ondelete: O que acontece ao registro atual quando o registro vinculado é excluído. As opções são
'cascade','set null'e'restrict'. O padrão é'set null'. - domain: Um filtro que restringe quais registros o usuário pode selecionar no dropdown. Por exemplo,
domain=[('customer_rank', '>', 0)]limita a seleção de parceiros apenas a clientes. - context: Valores de contexto adicionais passados ao abrir o registro relacionado ou o dropdown. Útil para preencher campos em registros relacionados recém-criados.
- required: Torna o campo obrigatório. O registro não pode ser salvo a menos que este campo esteja definido.
- readonly: Impede que os usuários alterem o registro vinculado. Útil quando o link é definido programaticamente e não deve ser alterado manualmente.
- delegate: Quando definido como
True, todos os campos do modelo relacionado tornam-se diretamente acessíveis no modelo atual. Isso é usado para herança de modelo no desenvolvimento Odoo, não para campos relacionais regulares.
Como Aparece nas Vistas
Em vistas de formulário, um campo Many2One é renderizado como um dropdown com um campo de busca. Os usuários podem digitar um nome parcial para filtrar a lista. Eles também podem clicar no ícone de seta ao lado do campo para abrir o registro vinculado diretamente, o que é muito útil para navegar entre documentos relacionados sem passar pelos menus.
Em vistas de lista, campos Many2One exibem o nome do registro vinculado. Eles suportam operações de agrupamento: você pode agrupar uma lista de pedidos de venda por cliente, ou uma lista de tarefas por projeto. Esse agrupamento é um dos recursos mais utilizados nos relatórios do Odoo.
Em vistas de pesquisa, campos Many2One podem ser usados como filtros e critérios de agrupamento. Quando você pesquisa por cliente no pipeline CRM, está filtrando em um campo Many2One.
O Recíproco One2Many
Cada relacionamento Many2One tem um reverso natural: o One2Many. Se os pedidos de venda estão ligados a um cliente via Many2One, o registro do cliente pode expor uma lista de todos os pedidos de venda vinculados através de um campo One2Many. No desenvolvimento do Odoo, é uma boa prática criar ambos os lados do relacionamento. Isso permite que os usuários naveguem do formulário do cliente para todos os seus pedidos sem realizar uma busca separada. O campo One2Many não adiciona uma coluna ao banco de dados; ele é calculado a partir da chave estrangeira Many2One do outro lado.
Casos de uso empresarial
O campo Many2One está presente em toda a implementação padrão do Odoo. Aqui estão cinco exemplos práticos de fluxos de trabalho empresariais reais.
CRM: Ligando Leads a Vendedores
No módulo CRM do Odoo, cada lead ou oportunidade tem um campo user_id, que é um Many2One apontando para res.users. Este é o vendedor responsável pelo lead. Os gerentes podem filtrar o pipeline por vendedor, visualizar taxas de conversão por representante e atribuir leads em massa. O campo Many2One torna esse tipo de segmentação e relatórios possível sem desenvolvimento personalizado. Se você quiser adicionar um segundo vendedor ou um campo dedicado de gerente de contas, basta adicionar outro campo Many2One apontando para o mesmo modelo.
Vendas: Conectando Pedidos a Clientes e Listas de Preços
Um pedido de venda no Odoo tem pelo menos dois campos Many2One importantes: partner_id (o cliente, vinculado a res.partner) e pricelist_id (a lista de preços, vinculada a product.pricelist). Quando um vendedor seleciona um cliente, o Odoo pode automaticamente preencher a lista de preços, as condições de pagamento e o endereço de entrega com base no registro do cliente. Esse preenchimento automático é impulsionado por métodos onchange que leem o valor Many2One e preenchem campos relacionados. É um dos benefícios mais visíveis de um modelo de dados Odoo bem estruturado.
Inventário: Produtos e Categorias
Cada produto no Odoo pertence a uma categoria de produto através de um campo Many2One (categ_id em product.template). A categoria do produto controla as contas contábeis para o custo das mercadorias vendidas e receita, métodos de avaliação e estratégias de remoção em armazéns. Obter a atribuição da categoria correta em cada produto é crítico para relatórios financeiros corretos. Um campo Many2One torna essa atribuição simples: um dropdown por produto, um registro de categoria compartilhado entre centenas de produtos.
Contabilidade: Lançamentos e Diários
Cada lançamento no Odoo está vinculado a um diário contábil através de um campo Many2One (journal_id em account.move). O diário determina a sequência usada para a numeração de documentos, o tipo de lançamento (venda, compra, banco, caixa, diversos) e, em alguns casos, as contas de débito e crédito padrão. Selecionar o diário errado em uma fatura de fornecedor ou um pagamento cria lançamentos na seção errada do livro razão. O campo Many2One aqui não é apenas uma conveniência; é um ponto de controle para a precisão contábil.
Gestão de Projetos: Tarefas e Projetos
No módulo de Projetos do Odoo, cada tarefa pertence a um projeto através de um campo Many2One (project_id em project.task). Este único link determina qual progresso de estágio a tarefa segue, quais membros da equipe podem acessá-la e como as folhas de ponto são alocadas. Para empresas de serviços profissionais que faturam por projeto, o link Many2One entre folhas de ponto, tarefas e o projeto pai é a espinha dorsal do reconhecimento de receita e dos fluxos de trabalho de faturamento.
Criando ou personalizando o campo Many2One
Existem três maneiras principais de adicionar um campo Many2One a um modelo Odoo, dependendo do seu contexto técnico e abordagem de implementação.
Usando Odoo Studio (Sem Código)
O Odoo Studio é a ferramenta de personalização de baixo código integrada. Para adicionar um campo Many2One sem escrever nenhum código:
- Abra o Odoo Studio a partir do menu principal.
- Navegue até o formulário onde você deseja o campo.
- Arraste um campo Many2One do seletor de campos para o formulário.
- No painel de propriedades, escolha o modelo de destino na lista.
- Defina o rótulo e qualquer filtro de domínio opcional para restringir quais registros os usuários podem selecionar.
- Salve e feche o Studio.
O Studio cria o campo com um prefixo x_studio_ e o adiciona automaticamente à visualização do formulário. O campo é imediatamente funcional: os usuários podem abrir o dropdown, pesquisar registros vinculados e selecionar um. Esta é uma das maneiras mais rápidas de estender um formulário com um link relacional, e não requer nenhum conhecimento técnico além de entender o que os dois modelos representam em seu negócio.
Usando Python em um Módulo Personalizado
Para desenvolvedores que estão construindo módulos Odoo, os campos Many2One são definidos diretamente em Python. Esta é a abordagem recomendada para qualquer desenvolvimento Odoo que precise ser controlado por versão e implantado em múltiplos ambientes:
from odoo import fields, models
class ProjectTask(models.Model):
_inherit = 'project.task'
x_client_contact_id = fields.Many2One(
comodel_name='res.partner',
string='Cliente Contacto',
domain=[('type', '=', 'contact')],
ondelete='set null',
help='O contacto principal no cliente para esta tarefa.',
)
Após definir o campo no modelo, inclua-o na visualização XML relevante e execute uma atualização para aplicar as alterações no banco de dados. Esta abordagem oferece controle total sobre filtros de domínio, comportamento de exclusão e integração com métodos de cálculo e restrições. É a abordagem padrão do guia do desenvolvedor Odoo para campos relacionais em módulos de produção.
Ao criar um Many2One como parte da personalização do Odoo, também é uma boa prática adicionar o campo correspondente One2Many no modelo relacionado para que os usuários possam navegar em ambas as direções da relação:
class ResPartner(models.Model):
_inherit = 'res.partner'
x_task_ids = fields.One2Many(
comodel_name='project.task',
inverse_name='x_client_contact_id',
string='Tarefas Relacionadas',
)
Usando a API XML-RPC
Se você estiver gerenciando personalizações do Odoo programaticamente, por exemplo, através de um script de implantação ou um caderno de configuração remota, você pode criar campos Many2One via a API XML-RPC:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_client_segment_id',
'field_description': 'Segmento do Cliente',
'model_id': model_id,
'ttype': 'many2one',
'relation': 'res.partner.category',
'on_delete': 'set null',
'state': 'manual',
}]
)
A chave relation especifica o modelo alvo. A chave on_delete define o comportamento de exclusão. Ao criar via API, lembre-se sempre de também criar o campo One2Many recíproco no modelo relacionado para que a navegação funcione de ambos os lados da relação. Esta é uma das regras obrigatórias nas configurações remotas do Dasolo para qualquer criação de campo Many2One.
Melhores práticas
1. Sempre crie o One2Many recíproco
Quando você adiciona um campo Many2One a um modelo, crie também o correspondente One2Many no modelo relacionado. Isso não custa uma coluna extra no banco de dados, mas torna a navegação muito mais natural para os usuários. Sem isso, os usuários não têm como ver a partir do formulário do cliente quais tarefas, pedidos ou registros personalizados estão vinculados a eles.
2. Use filtros de domínio para restringir a seleção
Um campo Many2One apontando para res.partner dá acesso a todos os parceiros por padrão, incluindo fornecedores, clientes, usuários internos e endereços de entrega. Se a lógica do seu negócio só faz sentido para clientes, adicione um filtro de domínio como domain=[('customer_rank', '>', 0)]. Isso reduz o ruído no menu suspenso e impede que os usuários façam seleções incorretas que parecem válidas, mas produzem resultados errados a montante.
3. Escolha o ondelete com cuidado
O comportamento ondelete importa mais do que parece. Usar 'cascade' significa que a exclusão do registro vinculado também excluirá todos os registros que apontam para ele. Isso pode causar exclusões em massa acidentais se não for intencional. Na maioria dos cenários de negócios, 'set null' é a escolha mais segura: limpa o vínculo sem excluir nada. Use 'restrict' quando o registro vinculado nunca deve ser excluído enquanto algo apontar para ele, por exemplo, uma categoria de produto que tenha produtos atribuídos a ela.
4. Evite duplicar dados que deveriam ser um Many2One
Um erro comum em projetos iniciais de personalização do Odoo é adicionar um campo char para armazenar um nome de empresa ou um rótulo de categoria, quando um Many2One apontando para um modelo existente seria a abordagem correta. Campos char para valores que já existem como registros em outro modelo criam duplicação de dados, tornam a filtragem e agrupamento não confiáveis e produzem inconsistências quando os nomes mudam. Se os dados que você precisa estão em outro modelo, use um Many2One.
5. Use contexto para preencher registros relacionados
O atributo context em um campo Many2One permite que você passe valores padrão quando os usuários criam um novo registro vinculado diretamente do dropdown. Por exemplo, se um Many2One aponta para um contato dentro de um projeto, você pode preencher automaticamente o projeto no novo registro de contato usando o contexto. Isso reduz a entrada manual e ajuda a manter a consistência dos dados quando os usuários criam registros relacionados rapidamente.
Armadilhas comuns
Esquecendo o One2Many recíproco
Adicionar um campo Many2One sem criar o inverso One2Many no modelo relacionado é a omissão mais comum na personalização do Odoo. O resultado é um vínculo unidirecional: você pode ver o registro vinculado a partir do modelo atual, mas a partir do registro vinculado você não tem como encontrar todos os registros que apontam para ele. Os usuários começam a reclamar que não conseguem encontrar registros relacionados, e alguém acaba construindo uma pesquisa ou relatório personalizado para compensar a falta de um campo inverso.
Usando exclusão em cascata sem pensar
Definir ondelete='cascade' em um Many2One que vincula registros operacionais a um registro mestre pode causar perda séria de dados. Se um usuário arquivar ou excluir uma categoria de produto, e todos os produtos vinculados a ela tiverem exclusão em cascata, cada produto nessa categoria desaparece. Na maioria dos casos, set null ou restrict é o comportamento apropriado para dados de negócios.
Não verificando por False ao navegar em Python
Quando um campo Many2One está vazio, lê-lo retorna um conjunto de registros vazio em Python, que é falso. Se seu código fizer order.partner_id.name sem verificar se partner_id está definido, ele retornará uma string vazia em vez de gerar um erro. Isso é frequentemente aceitável, mas se você navegar vários níveis profundos (order.partner_id.country_id.name) e qualquer vínculo na cadeia estiver vazio, você obterá uma string vazia no final, o que pode produzir silenciosamente uma saída errada em relatórios ou e-mails. Sempre verifique conjuntos de registros vazios quando o campo não for obrigatório.
Apontando para o modelo errado
No Odoo, res.partner é utilizado para clientes, fornecedores, contactos e empresas tudo ao mesmo tempo. Um Many2One apontando para res.partner sem um filtro de domínio dá acesso a todos eles. Se você pretendia que o campo fosse apenas para clientes, mas esqueceu o domínio, os vendedores verão utilizadores internos, endereços de entrega e contactos de fornecedores no dropdown. Sempre defina um filtro de domínio que corresponda à intenção real do negócio do campo.
Usando em excesso Many2One onde um campo Selection seria suficiente
Se os valores vinculados são uma lista fixa e pequena que nunca muda, um campo Selection é frequentemente mais simples e mais eficiente do que um Many2One. Campos Many2One requerem um modelo separado com registos, e adicionam uma junção de base de dados em cada consulta. Para algo como um estado com três ou quatro opções, um campo Selection é mais limpo. Use Many2One quando o conjunto de valores possíveis for grande, gerido por utilizadores, ou partilhado entre vários modelos.
Conclusão
O campo Many2One está no coração de como o Odoo conecta dados entre módulos. Compreendê-lo não é apenas uma preocupação de desenvolvedores. Analistas de negócios, consultores funcionais e utilizadores avançados que desejam estender o Odoo com o Studio beneficiam de saber o que um Many2One faz, quando usar um, e o que observar.
Os pontos-chave a lembrar: crie sempre o recíproco One2Many para que a navegação funcione de ambos os lados, use filtros de domínio para manter os dropdowns limpos e relevantes, escolha o seu comportamento ondelete deliberadamente, e evite usar Many2One onde um campo Selection mais simples faria o trabalho.
Quer você esteja configurando um campo através do Odoo Studio, escrevendo um módulo Python personalizado, ou gerindo o seu modelo de dados Odoo através da API XML-RPC, acertar os campos relacionais desde o início torna a sua implementação mais fiável e muito mais fácil de manter ao longo do tempo.
Na Dasolo, ajudamos empresas a implementar, personalizar e otimizar o Odoo em todos os departamentos. Quer precise de ajuda para desenhar um modelo de dados limpo, adicionar campos relacionais aos seus formulários, ou construir um módulo Odoo completo do zero, a nossa equipa está aqui para apoiar você. Entre em contato conosco e vamos conversar sobre o seu projeto Odoo.