Обратный поиск внешних ключей в Django

Django - это эффективная среда веб-разработки, которая упрощает создание веб-приложений. Django упрощает проверку подлинности и авторизацию, создание HTML-шаблонов, работу со статическими файлами, взаимодействие с базами данных и выполнение операций CRUD над ними.
Говоря о базах данных, Django упрощает большинство запросов, которые вы можете делать при работе с базами данных. Один из таких запросов - обратный взгляд; Например, нам нужно получить все объекты таблицы, которые ссылаются на конкретную запись той же таблицы или другой модели.
Эта статья покажет, насколько просто выполнить обратный поиск внешних ключей в Django.
Обратный поиск в моделях Django
Прежде чем мы перейдем к собственному этапу, нам понадобятся несколько моделей или таблиц для демонстрации. Мы будем рассматривать две сущности: учитель и ученик. У ученика есть два типа учителей; классный руководитель и любимый педагог. Модель Student
отсылает к модели 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")
Два поля модели Student
ссылаются на модель Teacher
. В Django, ссылаясь на одну и ту же модель более одного раза, мы должны предоставить related_name
для всех полей, потому что по умолчанию related_name
Django для одного поля ссылки конфликтует с другими полями ссылки. В противном случае Django выдаст исключение.
related_name
- это то, что мы используем для обратного поиска. В общем, рекомендуется указывать related_name
для всех внешних ключей, а не использовать имя, связанное с Django по умолчанию.
Пример 1
У нас есть учитель, у которого id
1
. Если нам нужно привлечь всех учеников, у которых этот человек является их классным руководителем, мы сделаем следующее:
teacher = Teacher.objects.get(id = 1)
students = teacher.classTeacherOf.all()
print(students) # A QuerySet of Student objects
Обратите внимание, как мы используем related_name
. teacher.classTeacherOf
- это объект-менеджер, что означает, что мы вызываем для него такие методы, как all()
, filter()
, exclude()
.
Пример 2
У нас есть учитель, у которого id
6
. Если нам нужно собрать всех учеников, которые считают этого учителя своим любимым учителем, мы сделаем что-то вроде этого:
teacher = Teacher.objects.get(id = 6)
students = teacher.favouriteTeacherOf.all()
print(students) # A QuerySet of Student objects
Пример 3
У нас есть учитель с id
25
. Если нам нужно проверить, является ли этот учитель классным руководителем ученика, чей id
равен 5
, мы сделаем следующее:
teacher = Teacher.objects.get(id = 25)
student = teacher.classTeacherOf.filter(id = 5)
print(student) # A QuerySet of either 1 or 0 Student
Обратите внимание, что если при обратном поиске объекты не найдены, возвращается пустой QuerySet
.