在Django中,ForeignKey 是用於表示一對多關係的欄位型別。它是模型中最常用的關聯欄位之一,用來定義模型與另一個模型之間的外來鍵關係。外來鍵關係是指一個模型的例項可以關聯到另一個模型的一個例項,從而建立資料之間的關聯。
1. 什麼是ForeignKey?
-
ForeignKey 欄位用於表示一對多的關係:一個模型的多個例項可以關聯到另一個模型的單個例項。
-
例如,在一個 Choice 模型中,多個選擇項可以關聯到同一個 Question 模型的例項。
2. ForeignKey的基本用法
定義一個外來鍵欄位時,需要指定目標模型(關聯的模型)以及外來鍵欄位的行為(例如,當關聯的物件被刪除時,如何處理關聯的物件)。
比如:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=100)
在上面的例子中:
-
Choice 模型中有一個 ForeignKey 欄位 question,它與 Question 模型關聯。
-
on_delete=models.CASCADE
指定了刪除 Question 物件時,相關的 Choice 物件也會被刪除。
3. ForeignKey 欄位的常用引數
-
to
:指定外來鍵關聯的目標模型(即一對多關係中的“多”側模型)。 -
on_delete
:指定當外來鍵關聯的目標物件被刪除時的行為。-
models.CASCADE
:當目標物件被刪除時,相關聯的物件也會被刪除。 -
models.SET_NULL
:當目標物件被刪除時,將外來鍵欄位設定為 NULL(前提是外來鍵欄位允許為 NULL)。 -
models.PROTECT
:當目標物件被刪除時,阻止刪除,並丟擲 ProtectedError 異常。 -
models.SET_DEFAULT
:當目標物件被刪除時,將外來鍵欄位設定為其預設值。 -
models.DO_NOTHING
:當目標物件被刪除時,不做任何操作。
-
比如:
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.SET_NULL, null=True)
choice_text = models.CharField(max_length=100)
在這個例子中,如果一個 Question 被刪除,相關的 Choice 物件的 question 欄位將被設定為 NULL
4. 外來鍵的反向關係:<model_name>_set
Django 為每個外來鍵欄位自動生成一個反向關係。這個反向關係使用小寫的模型名稱加上 _set 字尾。
比如:
question = Question.objects.create(question_text="What is your favorite color?")
choice1 = Choice.objects.create(question=question, choice_text="Red")
choice2 = Choice.objects.create(question=question, choice_text="Blue")
可以透過 question.choice_set.all()
訪問與 question 關聯的所有 Choice 物件。
choices = question.choice_set.all()
for choice in choices:
print(choice.choice_text)
輸出:
Red
Blue
5. 外來鍵的查詢:使用ForeignKey進行過濾
可以透過外來鍵欄位進行過濾查詢。例如,獲取所有與某個問題相關的選擇項:
choices = Choice.objects.filter(question__question_text="What is your favorite color?")
這裡的 question__question_text
使用了雙下劃線(__
)來跨越外來鍵關係進行欄位查詢。
6. 總結:ForeignKey的關鍵點
-
外來鍵關係:定義了一對多關係,其中一個物件的多條記錄可以指向另一個物件的單一記錄。
-
反向關係:Django 自動為每個外來鍵欄位建立反向關係,允許你訪問與某個物件相關聯的所有物件(使用
<model_name>_set
)。 -
on_delete
:指定當目標物件被刪除時,外來鍵欄位如何處理(如刪除關聯物件、將外來鍵設定為NULL等)。 -
外來鍵查詢:可以透過外來鍵欄位來過濾查詢,使用雙下劃線(
__
)跨越關係查詢欄位。
總結程式碼:
class Question(models.Model):
question_text = models.CharField(max_length=200)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=100)
# 建立問題和選項
question = Question.objects.create(question_text="What is your favorite color?")
Choice.objects.create(question=question, choice_text="Red")
Choice.objects.create(question=question, choice_text="Blue")
# 透過反向關係訪問相關的選項
choices = question.choice_set.all() # 獲取與該問題相關的所有選擇
for choice in choices:
print(choice.choice_text) # 輸出:Red, Blue
# 外來鍵查詢
choices = Choice.objects.filter(question__question_text="What is your favorite color?")