通過related_name反向關(guān)系字段 和 外鍵字段進行表對象之間的數(shù)據(jù)查詢
一、通過related_name去查詢相關(guān)數(shù)據(jù)
反向查詢(其實就是主表查詢的時候用的從表中定義的反向關(guān)系關(guān)聯(lián)字段進入到從表里面去獲取數(shù)據(jù),
不定義反向關(guān)系關(guān)聯(lián)字段的話,就是通過從表模型類名小寫_set,進入到從表里面去獲取數(shù)據(jù),優(yōu)先推薦定義反向關(guān)系關(guān)聯(lián)字段)
例如下面的實例:project1.interfaces.all()獲取project1 關(guān)聯(lián)的所有 Interface 實例,調(diào)用 .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' 是一個關(guān)鍵參數(shù),定義了如何通過 Project 實例訪問與之相關(guān)的所有 Interface 實例。
1. related_name 的作用:
在這段代碼中,related_name='interfaces' 的作用是為反向關(guān)系指定名稱。反向關(guān)系是指:通過 Project 模型實例,你可以訪問所有與該項目關(guān)聯(lián)的 Interface 實例。
詳細解釋:
1.ForeignKey('projects.Project', ...):表示在 Interfaces 模型中有一個外鍵指向 Project 模型,即每個接口(Interface)都屬于一個項目(Project)。
2.related_name='interfaces':這是 ForeignKey 的反向關(guān)系名稱。它指定了通過 Project 模型實例來訪問所有相關(guān)的 Interface 實例時使用的名稱。
具體來說,Django 會在 Project 模型中自動創(chuàng)建一個屬性 interfaces,這個屬性將返回所有關(guān)聯(lián)的 Interface 實例。通過這個屬性,你可以訪問到與某個項目相關(guān)的所有接口。
2. 反向關(guān)系的示例:
假設(shè)你有以下數(shù)據(jù):
3.一個 Project 實例表示一個項目 project1。
4.若干個 Interface 實例,每個接口都關(guān)聯(lián)到 project1。
你可以通過 related_name='interfaces' 在 Project 實例中訪問該項目的所有接口。
示例數(shù)據(jù):
# 創(chuàng)建項目
project1 = Project.objects.create(name='Project 1')
# 創(chuàng)建一些接口并關(guān)聯(lián)到該項目
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)
反向關(guān)系的查詢:
在沒有 related_name 的情況下,你只能通過默認的 interface_set 來訪問相關(guān)接口,但有了 related_name='interfaces',你可以通過更直觀的方式訪問接口。
# 通過項目實例訪問所有相關(guān)接口
project1_interfaces = project1.interfaces.all()
解析:
5.project1.interfaces.all() 查詢 project1 所有關(guān)聯(lián)的接口。由于我們設(shè)置了 related_name='interfaces',Django 會在 Project 模型中創(chuàng)建一個 interfaces 屬性,使用這個屬性你可以輕松地訪問所有與該項目相關(guān)的接口。
輸出:
# 輸出結(jié)果將是類似:
# <QuerySet [<Interfaces: Interface 1>, <Interfaces: Interface 2>, <Interfaces: Interface 3>]>
你可以通過 project1.interfaces.all() 獲取與 project1 關(guān)聯(lián)的所有 Interface 實例,調(diào)用 .name 可以查看它們的名字:
for interface in project1.interfaces.all():
print(interface.name)
輸出:
Interface 1
Interface 2
Interface 3
3. 為什么使用 related_name?
6.避免命名沖突:如果沒有設(shè)置 related_name,Django 默認會在反向關(guān)系中使用 modelname_set,例如 interface_set。如果你的模型中有多個外鍵指向同一模型(在本例中是 Project 模型),可能會出現(xiàn)命名沖突。這時,related_name 允許你為每個外鍵指定不同的反向關(guān)系名稱,避免命名沖突。
7.提高可讀性:通過設(shè)置 related_name='interfaces',你使代碼更加直觀。當(dāng)開發(fā)者看到 project1.interfaces.all() 時,能立即理解這是獲取與該項目相關(guān)的所有接口,代碼更具可讀性和表達性。
4. 默認行為與 related_name 區(qū)別:
假如沒有設(shè)置 related_name,Django 會自動為 Project 模型生成反向關(guān)系名 interface_set(即以小寫模型名加 _set)。例如:
project1.interface_set.all()
但是,使用 related_name='interfaces' 后,你可以更方便地訪問:
project1.interfaces.all() # 更直觀
總結(jié):
related_name='interfaces' 的作用是為 Project 模型提供一個反向關(guān)系的名稱,通過這個名稱,您可以方便地從 Project 實例訪問所有關(guān)聯(lián)的 Interface 實例。通過設(shè)置反向關(guān)系的名稱,Django ORM 提供了更靈活的查詢方式,同時避免了可能的命名沖突。
二、通過外鍵字段查詢出所關(guān)聯(lián)父表的數(shù)據(jù)
正向查詢(其實就是從表通過定義的外鍵,進入到主表中獲取數(shù)據(jù),
例如下面的實例:interface1.projects.name獲取interface1實例所關(guān)聯(lián)的項目名稱)
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 字段來訪問關(guān)聯(lián)的項目。
1. 如何查詢接口所屬項目
假設(shè)你有三個接口實例,你想知道它們分別屬于哪個項目,你可以直接通過 projects 字段來查詢。
2. 代碼示例
首先,創(chuàng)建一些數(shù)據(jù)(接口和項目):
# 假設(shè)我們有兩個項目
project1 = Project.objects.create(name='Project 1')
project2 = Project.objects.create(name='Project 2')
# 創(chuàng)建接口并關(guān)聯(lián)到項目
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 字段的反向查詢
如果你已經(jīng)有一個 Interface 實例并想通過它查詢所屬的項目,直接訪問 projects 字段即可。每個 Interfaces 實例都通過 projects 外鍵與對應(yīng)的 Project 實例關(guān)聯(lián)。
1.interface1.projects 會返回 Project 1 實例。
2.interface2.projects 會返回 Project 1 實例。
3.interface3.projects 會返回 Project 2 實例。
5. 查詢多個接口所屬的項目
如果你有多個接口實例,可以通過循環(huán)逐個查詢它們所屬的項目:
# 獲取所有接口
interfaces = Interfaces.objects.all()
# 輸出每個接口所屬的項目
for interface in interfaces:
print(f'{interface.name} 屬于項目: {interface.projects.name}')
輸出結(jié)果:
Interface 1 屬于項目: Project 1
Interface 2 屬于項目: Project 1
Interface 3 屬于項目: Project 2
6. 總結(jié):
4.查詢接口所屬項目:通過 projects 字段可以查詢每個接口所關(guān)聯(lián)的項目。例如,interface.projects.name 可以訪問該接口所屬項目的名稱。
5.反向關(guān)系:通過外鍵字段(projects)可以訪問關(guān)聯(lián)的項目,反向查詢時使用的是 related_name 中指定的名稱 interfaces(如果你需要從項目查找所有接口)。
因此,通過外鍵字段 projects,你可以輕松地查詢每個接口所屬的項目。

浙公網(wǎng)安備 33010602011771號