通过related_name反向关系字段 和 外键字段进行表对象之间的数据查询

一、通过related_name去查询相关数据

反向查询(其实就是主表查询的时候用的从表中定义的反向关系关联字段进入到从表里面去获取数据,

不定义反向关系关联字段的话,就是通过从表模型类名小写_set,进入到从表里面去获取数据,优先推荐定义反向关系关联字段)
例如下面的实例:project1.interfaces.all()获取project1 关联的所有 Interface 实例,调用 .name 可以查看它们的名字
for interface in project1.interfaces.all():
print(interface.name)


代码解析:
class Interfaces(models.Model):
    name = models.CharField(verbose_name='接口名称', help_text='请输入接口名称', max_length=50)
    projects = models.ForeignKey('projects.Project', on_delete=models.CASCADE,
                                 verbose_name='所属项目id', help_text='请输入所属项目id',
                                 related_name='interfaces')

在这个 Interfaces 模型中,projects 字段是一个外键,指向 projects.Project 模型。外键 projects 表示每个 Interface 实例都属于一个 Project 实例(即每个接口都属于某个项目)。这里 related_name='interfaces' 是一个关键参数,定义了如何通过 Project 实例访问与之相关的所有 Interface 实例。
1. related_name 的作用:
在这段代码中,related_name='interfaces' 的作用是为反向关系指定名称。反向关系是指:通过 Project 模型实例,你可以访问所有与该项目关联的 Interface 实例。
详细解释:

1.ForeignKey('projects.Project', ...):表示在 Interfaces 模型中有一个外键指向 Project 模型,即每个接口(Interface)都属于一个项目(Project)。
2.related_name='interfaces':这是 ForeignKey 的反向关系名称。它指定了通过 Project 模型实例来访问所有相关的 Interface 实例时使用的名称。

具体来说,Django 会在 Project 模型中自动创建一个属性 interfaces,这个属性将返回所有关联的 Interface 实例。通过这个属性,你可以访问到与某个项目相关的所有接口。
2. 反向关系的示例:
假设你有以下数据:

3.一个 Project 实例表示一个项目 project1。
4.若干个 Interface 实例,每个接口都关联到 project1。

你可以通过 related_name='interfaces' 在 Project 实例中访问该项目的所有接口。
示例数据:
# 创建项目
project1 = Project.objects.create(name='Project 1')

# 创建一些接口并关联到该项目
interface1 = Interfaces.objects.create(name='Interface 1', projects=project1)
interface2 = Interfaces.objects.create(name='Interface 2', projects=project1)
interface3 = Interfaces.objects.create(name='Interface 3', projects=project1)

反向关系的查询:
在没有 related_name 的情况下,你只能通过默认的 interface_set 来访问相关接口,但有了 related_name='interfaces',你可以通过更直观的方式访问接口。
# 通过项目实例访问所有相关接口
project1_interfaces = project1.interfaces.all()

解析:

5.project1.interfaces.all() 查询 project1 所有关联的接口。由于我们设置了 related_name='interfaces',Django 会在 Project 模型中创建一个 interfaces 属性,使用这个属性你可以轻松地访问所有与该项目相关的接口。

输出:
# 输出结果将是类似:
# <QuerySet [<Interfaces: Interface 1>, <Interfaces: Interface 2>, <Interfaces: Interface 3>]>

你可以通过 project1.interfaces.all() 获取与 project1 关联的所有 Interface 实例,调用 .name 可以查看它们的名字:
for interface in project1.interfaces.all():
    print(interface.name)

输出:
Interface 1
Interface 2
Interface 3

3. 为什么使用 related_name?

6.避免命名冲突:如果没有设置 related_name,Django 默认会在反向关系中使用 modelname_set,例如 interface_set。如果你的模型中有多个外键指向同一模型(在本例中是 Project 模型),可能会出现命名冲突。这时,related_name 允许你为每个外键指定不同的反向关系名称,避免命名冲突。
7.提高可读性:通过设置 related_name='interfaces',你使代码更加直观。当开发者看到 project1.interfaces.all() 时,能立即理解这是获取与该项目相关的所有接口,代码更具可读性和表达性。

4. 默认行为与 related_name 区别:
假如没有设置 related_name,Django 会自动为 Project 模型生成反向关系名 interface_set(即以小写模型名加 _set)。例如:
project1.interface_set.all()

但是,使用 related_name='interfaces' 后,你可以更方便地访问:
project1.interfaces.all()  # 更直观

总结:
related_name='interfaces' 的作用是为 Project 模型提供一个反向关系的名称,通过这个名称,您可以方便地从 Project 实例访问所有关联的 Interface 实例。通过设置反向关系的名称,Django ORM 提供了更灵活的查询方式,同时避免了可能的命名冲突。

二、通过外键字段查询出所关联父表的数据

正向查询(其实就是从表通过定义的外键,进入到主表中获取数据,

例如下面的实例:interface1.projects.name获取interface1实例所关联的项目名称)

class Interfaces(models.Model):
    name = models.CharField(verbose_name='接口名称', help_text='请输入接口名称', max_length=50)
    projects = models.ForeignKey('projects.Project', on_delete=models.CASCADE,
                                 verbose_name='所属项目id', help_text='请输入所属项目id',
                                 related_name='interfaces')
在你提供的模型中,Interfaces 模型有一个外键 projects,指向 projects.Project 模型,表示每个接口属于一个项目。因此,要查询已知接口属于哪个项目,可以通过 projects 字段来访问关联的项目。
1. 如何查询接口所属项目
假设你有三个接口实例,你想知道它们分别属于哪个项目,你可以直接通过 projects 字段来查询。
2. 代码示例
首先,创建一些数据(接口和项目):
# 假设我们有两个项目
project1 = Project.objects.create(name='Project 1')
project2 = Project.objects.create(name='Project 2')

# 创建接口并关联到项目
interface1 = Interfaces.objects.create(name='Interface 1', projects=project1)
interface2 = Interfaces.objects.create(name='Interface 2', projects=project1)
interface3 = Interfaces.objects.create(name='Interface 3', projects=project2)

此时,interface1 和 interface2 属于 project1,interface3 属于 project2。
3. 查询每个接口所属的项目
对于每个 Interfaces 实例,你可以通过 projects 字段查询它所属的项目。例如:
# 查询接口1所属的项目
print(interface1.projects.name)  # 输出 Project 1

# 查询接口2所属的项目
print(interface2.projects.name)  # 输出 Project 1

# 查询接口3所属的项目
print(interface3.projects.name)  # 输出 Project 2

4. 使用 projects 字段的反向查询
如果你已经有一个 Interface 实例并想通过它查询所属的项目,直接访问 projects 字段即可。每个 Interfaces 实例都通过 projects 外键与对应的 Project 实例关联。

1.interface1.projects 会返回 Project 1 实例。
2.interface2.projects 会返回 Project 1 实例。
3.interface3.projects 会返回 Project 2 实例。

5. 查询多个接口所属的项目
如果你有多个接口实例,可以通过循环逐个查询它们所属的项目:
# 获取所有接口
interfaces = Interfaces.objects.all()

# 输出每个接口所属的项目
for interface in interfaces:
    print(f'{interface.name} 属于项目: {interface.projects.name}')

输出结果:
Interface 1 属于项目: Project 1
Interface 2 属于项目: Project 1
Interface 3 属于项目: Project 2

6. 总结:

4.查询接口所属项目:通过 projects 字段可以查询每个接口所关联的项目。例如,interface.projects.name 可以访问该接口所属项目的名称。
5.反向关系:通过外键字段(projects)可以访问关联的项目,反向查询时使用的是 related_name 中指定的名称 interfaces(如果你需要从项目查找所有接口)。

因此,通过外键字段 projects,你可以轻松地查询每个接口所属的项目。




posted @ 2025-09-10 18:02  大海一个人听  阅读(13)  评论(0)    收藏  举报