<!--
譯者:Github@wizardforcel
-->
# 關聯對象參考 #
**class RelatedManager**
"關聯管理器"是在一對多或者多對多的關聯上下文中使用的管理器。它存在于下面兩種情況:
ForeignKey關系的“另一邊”。像這樣:
```
from django.db import models
class Reporter(models.Model):
# ...
pass
class Article(models.Model):
reporter = models.ForeignKey(Reporter)
```
在上面的例子中,管理器reporter.article_set擁有下面的方法。
ManyToManyField關系的兩邊:
```
class Topping(models.Model):
# ...
pass
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
```
這個例子中,topping.pizza_set 和pizza.toppings都擁有下面的方法。
**add(obj1[, obj2, ...])**
把指定的模型對象添加到關聯對象集中。
例如:
```
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Associates Entry e with Blog b.
```
在上面的例子中,對于ForeignKey關系,e.save()由關聯管理器調用,執行更新操作。然而,在多對多關系中使用add()并不會調用任何 save()方法,而是由QuerySet.bulk_create()創建關系。如果你需要在關系被創建時執行一些自定義的邏輯,請監聽m2m_changed信號。
**create(\*\*kwargs)**
創建一個新的對象,保存對象,并將它添加到關聯對象集之中。返回新創建的對象:
```
>>> b = Blog.objects.get(id=1)
>>> e = b.entry_set.create(
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
# No need to call e.save() at this point -- it's already been saved.
```
這完全等價于(不過更加簡潔于):
```
>>> b = Blog.objects.get(id=1)
>>> e = Entry(
... blog=b,
... headline='Hello',
... body_text='Hi',
... pub_date=datetime.date(2005, 1, 1)
... )
>>> e.save(force_insert=True)
```
要注意我們并不需要指定模型中用于定義關系的關鍵詞參數。在上面的例子中,我們并沒有傳入blog參數給create()。Django會明白新的 Entry對象blog 應該添加到b中。
**remove(obj1[, obj2, ...])**
從關聯對象集中移除執行的模型對象:
```
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
```
和add()相似,上面的例子中,e.save()可會執行更新操作。但是,多對多關系上的remove(),會使用QuerySet.delete()刪除關系,意思是并不會有任何模型調用save()方法:如果你想在一個關系被刪除時執行自定義的代碼,請監聽m2m_changed信號。
對于ForeignKey對象,這個方法僅在null=True時存在。如果關聯的字段不能設置為None (NULL),則這個對象在添加到另一個關聯之前不能移除關聯。在上面的例子中,從b.entry_set()移除e等價于讓e.blog = None,由于blog的ForeignKey沒有設置null=True,這個操作是無效的。
對于ForeignKey對象,該方法接受一個bulk參數來控制它如果執行操作。如果為True(默認值),QuerySet.update()會被使用。而如果bulk=False,會在每個單獨的模型實例上調用save()方法。這會觸發pre_save和post_save,它們會消耗一定的性能。
**clear()**
從關聯對象集中移除一切對象。
```
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
```
注意這樣不會刪除對象 —— 只會刪除他們之間的關聯。
就像 remove() 方法一樣,clear()只能在 null=True的ForeignKey上被調用,也可以接受bulk關鍵詞參數。
> 注意
>
> 注意對于所有類型的關聯字段,add()、create()、remove()和clear()都會馬上更新數據庫。換句話說,在關聯的任何一端,都不需要再調用save()方法。
>
> 同樣,如果你再多對多關系中使用了中間模型,一些關聯管理的方法會被禁用。
## 直接賦值 ##
通過賦值一個新的可迭代的對象,關聯對象集可以被整體替換掉。
```
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
```
如果外鍵關系滿足null=True,關聯管理器會在添加new_list中的內容之前,首先調用clear()方法來解除關聯集中一切已存在對象的關聯。否則, new_list中的對象會在已存在的關聯的基礎上被添加。
- 新手入門
- 從零開始
- 概覽
- 安裝
- 教程
- 第1部分:模型
- 第2部分:管理站點
- 第3部分:視圖和模板
- 第4部分:表單和通用視圖
- 第5部分:測試
- 第6部分:靜態文件
- 高級教程
- 如何編寫可重用的應用
- 為Django編寫首個補丁
- 模型層
- 模型
- 模型語法
- 元選項
- 模型類
- 查詢集
- 執行查詢
- 查找表達式
- 模型的實例
- 實例方法
- 訪問關聯對象
- 遷移
- 模式編輯器
- 編寫遷移
- 高級
- 管理器
- 原始的SQL查詢
- 聚合
- 多數據庫
- 自定義查找
- 條件表達式
- 數據庫函數
- 其它
- 遺留的數據庫
- 提供初始數據
- 優化數據庫訪問
- 視圖層
- 基礎
- URL配置
- 視圖函數
- 快捷函數
- 裝飾器
- 參考
- 內建的視圖
- TemplateResponse 對象
- 文件上傳
- 概覽
- File 對象
- 儲存API
- 管理文件
- 自定義存儲
- 基于類的視圖
- 概覽
- 內建顯示視圖
- 內建編輯視圖
- API參考
- 分類索引
- 高級
- 生成 CSV
- 生成 PDF
- 中間件
- 概覽
- 內建的中間件類
- 模板層
- 基礎
- 面向設計師
- 語言概覽
- 人性化
- 面向程序員
- 表單
- 基礎
- 概覽
- 表單API
- 內建的Widget
- 高級
- 整合媒體
- 開發過程
- 設置
- 概覽
- 應用程序
- 異常
- 概覽
- django-admin 和 manage.py
- 添加自定義的命令
- 測試
- 介紹
- 部署
- 概述
- WSGI服務器
- 部署靜態文件
- 通過email追蹤代碼錯誤
- Admin
- 管理操作
- 管理文檔生成器
- 安全
- 安全概述
- 說明Django中的安全問題
- 點擊劫持保護
- 加密簽名
- 國際化和本地化
- 概述
- 本地化WEB UI格式化輸入
- “本地特色”
- 常見的網站應用工具
- 認證
- 概覽
- 使用認證系統
- 密碼管理
- 日志
- 分頁
- 會話
- 數據驗證
- 其它核心功能
- 按需內容處理
- 重定向
- 信號
- 系統檢查框架