django 1.8 官方文檔翻譯: 2-3-2 關聯對象參考

關聯對象參考

class RelatedManagerhtml

"關聯管理器"是在一對多或者多對多的關聯上下文中使用的管理器。它存在於下面兩種狀況:python

ForeignKey關係的「另外一邊」。像這樣:git

from django.db import models

class Reporter(models.Model):
    # ...
    pass

class Article(models.Model):
    reporter = models.ForeignKey(Reporter)

在上面的例子中,管理器reporter.article_set擁有下面的方法。github

ManyToManyField關係的兩邊:數據庫

class Topping(models.Model):
    # ...
    pass

class Pizza(models.Model):
    toppings = models.ManyToManyField(Topping)

這個例子中,topping.pizza_set 和pizza.toppings都擁有下面的方法。django

add(obj1[, obj2, ...])sass

把指定的模型對象添加到關聯對象集中。post

例如:性能

>>> 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信號。this

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中的對象會在已存在的關聯的基礎上被添加。

譯者:飛龍,原文:Accessing related objects

本文以 CC BY-NC-SA 3.0 協議發佈,轉載請保留做者署名和文章出處。

Django 文檔協做翻譯小組人手緊缺,有興趣的朋友能夠加入咱們,徹底公益性質。交流羣:467338606。

若是以爲文章還不錯,能夠掃描下面的二維碼來打賞我。

相關文章
相關標籤/搜索