Django中多對多關系三種定義方式
Django 中的多對多關系(ManyToManyField)可以通過 三種方式定義,它們在使用便捷性和可擴展性上各有差異。以下是完整總結 ? 并注明每種方式中哪些方法不可用:
? 方式一:默認方式(Django 自動創(chuàng)建中間表)
? 特點:
- 最常用、最方便
- Django 自動生成中間表
- 不支持自定義字段
? 示例:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
? 可用方法:
| 方法 | 可用? | 說明 |
|---|---|---|
| .add(obj) | ? | 添加關聯(lián) |
| .remove(obj) | ? | 移除關聯(lián) |
| .set([obj1, obj2]) | ? | 重新設置關聯(lián) |
| .clear() | ? | 清除所有關聯(lián) |
| .all() | ? | 查詢所有關聯(lián)對象 |
? 方式二:使用 through 自定義中間表(推薦用于需要額外字段的情況)
? 特點:
- 中間模型可添加自定義字段(如創(chuàng)建時間、角色等)
- 更靈活,但略復雜
? 示例:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(
Author,
through="BookAuthor",
through_fields=("book", "author")
)
class BookAuthor(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
? 禁用方法:
| 方法 | 可用? | 說明 |
|---|---|---|
| .add(obj) | ? | 被禁用,Django 不知道如何填中間表 |
| .remove(obj) | ? | ? 同上 |
| .set([obj1, obj2]) | ? | ? 同上 |
| .clear() | ? | ? 同上 |
| .all() | ? | 查詢仍然可用 |
? 正確操作方式:
使用中間模型手動添加:
BookAuthor.objects.create(book=book, author=author)
? 方式三:完全手動中間表,無 ManyToManyField
? 特點:
- 不定義
ManyToManyField - 所有關系自己通過中間表查詢管理
- 最靈活,但也最復雜,不推薦日常使用
? 示例:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
class BookAuthor(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
added_at = models.DateTimeField(auto_now_add=True)
? 所有 .authors.xxx 都不可用
| 方法 | 可用? | 說明 |
|---|---|---|
| .add() / .remove() / 等 | ? | 沒有 ManyToManyField 字段 |
| .all() | ? | 也不能直接訪問 .authors.all() |
| 查詢方式 | ? | 需手動通過中間表查詢 |
# 查詢一本書的所有作者
BookAuthor.objects.filter(book=book).select_related("author")
# 查詢一個作者的所有書
BookAuthor.objects.filter(author=author).select_related("book")
? 總結對比表
| 方式 | 是否有中間模型 | 是否能添加中間字段 | 快捷方法(add/remove/set) | 推薦用途 |
|---|---|---|---|---|
| 默認 ManyToManyField | ?(Django 自動) | ? | ? 可用 | 簡單多對多關系 |
| ManyToManyField + through | ? | ? | ? 被禁用 | 多對多且需附加字段場景 |
| 完全手動中間模型 | ? | ? | ? 全部禁用 | 高度自定義業(yè)務、底層控制場景 |
在 Django 中,ManyToManyField 提供了一套專門用于 增刪改查(CRUD) 的方法,用于操作模型之間的多對多關系。以下是完整的 CRUD 方法總結(適用于未使用 through 中間模型的情況):
? Django 多對多的 CRUD 方法匯總
假設模型如下:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
? 1. C:創(chuàng)建關系(Create)
? 方法一:創(chuàng)建對象后添加關聯(lián)
book = Book.objects.create(title="Python入門") author = Author.objects.create(name="張三") book.authors.add(author) # 添加關聯(lián)關系
? 方法二:一次添加多個對象
book.authors.add(author1, author2, author3)
? 2. R:查詢關系(Read)
# 查詢某本書的所有作者 book.authors.all() # 查詢某個作者參與的所有書(反向查詢) author.book_set.all() # 如果設置了 related_name="books",可以用: author.books.all()
? 3. U:更新關系(Update)
? 重新設置關系(會先清空原有關系再添加新關系)
book.authors.set([author1, author2]) # 只保留這兩個作者
? 4. D:刪除關系(Delete)
? 刪除指定的某個或多個關系:
book.authors.remove(author1) book.authors.remove(author1, author2)
? 清除所有關系:
book.authors.clear()
? 使用限制說明(重要)
| 方法 | 是否可用 | 條件說明 |
|---|---|---|
| .add() | ? | 不能用于通過 through 自定義中間模型 |
| .remove() | ? | 同上 |
| .clear() | ? | 同上 |
| .set() | ? | 同上 |
| .all() | ? | 始終可用 |
? 如果你在 ManyToManyField 中使用了 through="XXX",上述 .add() 等方法會全部失效,必須手動操作中間模型。
? 5. 示例:完整流程演示
# 添加關系
book = Book.objects.create(title="FastAPI進階")
author1 = Author.objects.create(name="Alice")
author2 = Author.objects.create(name="Bob")
book.authors.add(author1, author2)
# 查詢關系
for author in book.authors.all():
print(author.name)
# 更新關系
book.authors.set([author2]) # 現(xiàn)在只有 Bob
# 刪除單個關系
book.authors.remove(author2)
# 清空所有關系
book.authors.clear()
到此這篇關于Django中多對多關系三種定義方式的文章就介紹到這了,更多相關Django 多對多關系創(chuàng)建內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
PyQt5結合QtDesigner實現(xiàn)文本框讀寫操作
本文將結合實例代碼,介紹PyQt5結合QtDesigner實現(xiàn)文本框讀寫操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-06-06
Gradio機器學習模型快速部署工具quickstart前篇
這篇文章主要為大家介紹了Gradio機器學習模型快速部署工具quickstart準備原文翻譯,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04
在tensorflow下利用plt畫論文中l(wèi)oss,acc等曲線圖實例
這篇文章主要介紹了在tensorflow下利用plt畫論文中l(wèi)oss,acc等曲線圖實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06

