Arquivo da tag: queryset

Criando joins customizados no Django

django

Durante o desenvolvimento de uma aplicação no framework Django você pode precisar realizar SQL puro, límpido e incolor.

O Django permite que você faça isso, mas certifique-se de ter feito o possível e o impossível para que isto não ocorra. Eu sei que criar consultas no Django às vezes parece coisa de tentativa e erro, mas sempre utilize as funções equivalentes dele para manter compatibilidade entre as engines diferentes de banco de dados.

Você pode achar que não irá precisar mudar de banco de dados futuramente, mas no meu caso já tive que manter aplicações em MySQL que depois precisaram migrar para Oracle. Em outras tinha que funcionar tanto em MySQL e PostgreSQL. Isso quando o ambiente de desenvolvimento era diferente do ambiente de produção…

Mas enfim, se não tiver jeito Raw SQL neles, mas não vou entrar em detalhes em como fazer essas queries no Django, pois até este ponto ele está bem documentado:

Porém esses dias me deparei com um problema muito específico no qual tinha que fazer o JOIN na mão. Bom, se você chegar ao ponto de ter que criar um JOIN na mão no Django, então realmente é um problema muito específico.

Não existe uma forma de se fazer isso no Django, pelo menos não documentada. Encontrei uma solução fazendo o uso do método join do objeto Query.

O join recebe uma tupla contendo as tabelas e campos do JOIN e um parâmetro promote que especifica se é um LEFT OUTER JOIN.

Exemplo:

qs = People.objects.all()

# ... inner join contact_people on contact_people.id=contact_phone.people_id
join_tuple = (
    'contact_people', # table 1
    'contact_phone', # table 2
    'id', # field 1
    'people_id' # field 2
)

qs.query.join(join_tuple, promote=True)

print qs.query # para ver o SQL gerado, cuidado com erros de encode.

É um exemplo simples e poderia ser feito utilizando os métodos normais disponibilizados pelo QuerySet. Você deve moldar para a solução do seu problema, pois como falei ela provavelmente deve ser muito específica. Na dúvida verifique o SQL gerado.

Além disso, com certeza não é a melhor forma de fazer os JOINs no Django. Funciona, mas teje avisado…