在 Django 中反向查找外键

Vaibhav Vaibhav 2021年8月10日
在 Django 中反向查找外键

Django 是一种高效的 Web 开发框架,可简化 Web 应用程序的创建。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,因为 Django 的单个引用字段的默认 related_name 会与其他引用字段发生冲突。否则,Django 将抛出异常。

related_name 是我们用于反向查找的内容。通常,为所有外键提供 related_name 是一个好习惯,而不是使用 Django 的默认相关名称。

示例 1

我们有一位老师,他的 id1。如果我们必须让所有有这个人作为班主任的学生,我们将执行以下操作:

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

请注意我们如何使用 related_nameteacher.classTeacherOf 是一个管理器对象,这意味着我们可以在其上调用 all()filter()exclude() 等方法。

示例 2

我们有一位老师,他的 id6。如果我们必须让所有认为这位老师是他们最喜欢的老师的学生,我们会这样做:

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

示例 3

我们有一位老师,他的 id25。如果我们要检查这个老师是否是一个 id5 的学生的班主任,我们将做如下操作:

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

请注意,如果在反向查找中没有找到对象,则返回一个空的 QuerySet

作者: Vaibhav Vaibhav
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.