Django中的ForeignKey
在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?")