Pesquisas reversas de chaves estrangeiras no Django

Vaibhav Vaibhav 10 agosto 2021
Pesquisas reversas de chaves estrangeiras no Django

Django é uma estrutura de desenvolvimento web eficiente que simplifica a criação de aplicativos web. Django torna fácil lidar com autenticação e autorização, criação de templates HTML, lidar com arquivos estáticos, interagir com bancos de dados e realizar operações CRUD sobre eles.

Falando em bancos de dados, o Django simplifica a maioria das consultas que você pode fazer enquanto trabalha com bancos de dados. Uma dessas perguntas é a aparência inversa; um exemplo é quando temos que obter todos os objetos de uma tabela que fazem referência a um determinado registro da mesma tabela ou de um modelo diferente.

Este artigo mostrará como é simples realizar pesquisas reversas de chaves estrangeiras no Django.

Pesquisas reversas em modelos Django

Antes de passarmos para a etapa real, precisamos de alguns modelos ou tabelas para demonstração. Vamos considerar duas entidades: professor e aluno. O aluno tem dois tipos de professores; um professor de classe e um professor favorito. O modelo Student faz referência ao modelo Teacher.

from django.db import models


class Teacher(models.Model):
    name = models.CharField(max_length=200)
    subject = models.CharField(max_length=200)


class Student(models.Model):
    name = models.CharField(max_length=200)
    classTeacher = models.ForeignKey(
        Teacher, on_delete=models.SET_NULL, null=True, related_name="classTeacherOf"
    )
    favouriteTeacher = models.ForeignKey(
        Teacher, on_delete=models.SET_NULL, null=True, related_name="favouriteTeacherOf"
    )

Dois campos do modelo Student fazem referência ao modelo Teacher. No Django, ao fazer referência ao mesmo modelo mais de uma vez, temos que fornecer um related_name para todos os campos porque o padrão related_name do Django para um único campo de referência entra em conflito com outros campos de referência. Caso contrário, o Django lançará uma exceção.

O related_name é o que usamos para a pesquisa inversa. Em geral, é uma boa prática fornecer um related_name para todas as chaves estrangeiras ao invés de usar o nome relacionado padrão do Django.

Exemplo 1

Temos um professor cujo id é 1. Se tivermos que obter todos os alunos que têm esse indivíduo como professor da turma, faremos o seguinte:

teacher = Teacher.objects.get(id=1)
students = teacher.classTeacherOf.all()
print(students)  # A QuerySet of Student objects

Observe como estamos usando o related_name. O teacher.classTeacherOf é um objeto gerenciador, o que significa que nele chamamos métodos como all(), filter(), exclude().

Exemplo 2

Temos um professor cujo id é 6. Se tivermos que conseguir todos os alunos que consideram esse professor como seu professor favorito, faremos algo assim:

teacher = Teacher.objects.get(id=6)
students = teacher.favouriteTeacherOf.all()
print(students)  # A QuerySet of Student objects

Exemplo 3

Temos um professor cujo id é 25. Se tivermos de verificar se este professor é o professor da turma de um aluno cujo id é 5, faremos o seguinte:

teacher = Teacher.objects.get(id=25)
student = teacher.classTeacherOf.filter(id=5)
print(student)  # A QuerySet of either 1 or 0 Student

Observe que, se nenhum objeto for encontrado na pesquisa reversa, um QuerySet vazio será retornado.

Vaibhav Vaibhav avatar Vaibhav Vaibhav avatar

Vaibhav is an artificial intelligence and cloud computing stan. He likes to build end-to-end full-stack web and mobile applications. Besides computer science and technology, he loves playing cricket and badminton, going on bike rides, and doodling.