Django `_set` 用法筆記(ForeignKey 反向關聯)
🔗 Django _set
用法筆記(ForeignKey 反向關聯)
✅ 基本觀念:一對多關係(ForeignKey)
假設有下列兩個 Model:
class Interview(models.Model):
title = models.CharField(max_length=100)
class Comment(models.Model):
interview = models.ForeignKey(Interview, on_delete=models.CASCADE)
content = models.TextField()
這裡代表:
- 一個
Interview
可以有多個Comment
Comment
是「多」方,透過 ForeignKey 指向「一」方的Interview
↻ 反向關聯:使用 _set
Django 會自動在一方的 model 加上一個反向屬性,名稱預設是:
<related_model_name>_set
所以可以這樣用:
interview.comment_set.all() # 查出這個 interview 底下的所有 comment
interview.comment_set.create(content='你好') # 新增一筆 comment 自動連結該 interview
📛 注意:預設反向屬性的命名方式
預設情況下,Django 會以「小寫 model 名稱 + _set
」為一方建立反向屬性。
例如:
class Comment(models.Model):
interview = models.ForeignKey(Interview, on_delete=models.CASCADE)
- 這會讓你能夠使用
interview.comment_set
來取得該 interview 所有的 comment。 - 若 model 名稱為
Message
,則會是article.message_set
若希望有更語意化的名稱,建議加上 related_name
(見下方)。
✍️ 常見用法整理:
# 取得所有 comment
comments = interview.comment_set.all()
# Interview 角度
# 建立一筆新的 comment 並與 interview 關聯
interview.comment_set.create(content=req.POST['content'])
# Comment 角度
Comment.objects.create(interview=interview, content=req.POST['content'])
💡 如何自訂反向名稱(最佳實踐)
為了讓語意更清楚,可以在 ForeignKey 中加上 related_name
:
class Comment(models.Model):
interview = models.ForeignKey(
Interview,
on_delete=models.CASCADE,
related_name='comments' # 自訂名稱
)
就能這樣使用:
interview.comments.all()
interview.comments.create(content='加油!')
💬 面試回答(Q&A)
Q: Django 中如何透過 ForeignKey 建立一對多關係,並如何查詢/建立子資料?
A:
在多方的 model 使用
ForeignKey
連到一方,並使用 Django 提供的反向屬性<model>_set
來存取。例如interview.comment_set.create(...)
可以新增一筆資料,同時建立關聯。如果加上related_name
可以讓語意更清楚,如interview.comments.create(...)
。