関連オブジェクトリファレンス
- class RelatedManager
「関連マネージャー」とは、1対多または多対多の関連コンテキストで使用されるマネージャーです。 これは2つの場合に発生します。
ForeignKey 関係の「反対側」。 あれは:
from django.db import models class Blog(models.Model): # ... pass class Entry(models.Model): blog = models.ForeignKey(Blog, on_delete=models.CASCADE, null=True)上記の例では、以下のメソッドはマネージャー
blog.entry_setで使用できます。ManyToManyField 関係の両側:
class Topping(models.Model): # ... pass class Pizza(models.Model): toppings = models.ManyToManyField(Topping)この例では、以下のメソッドは
topping.pizza_setとpizza.toppingsの両方で使用できます。
- add(*objs, bulk=True, through_defaults=None)
指定されたモデルオブジェクトを関連するオブジェクトセットに追加します。
例:
>>> b = Blog.objects.get(id=1) >>> e = Entry.objects.get(id=234) >>> b.entry_set.add(e) # Associates Entry e with Blog b.上記の例では、 ForeignKey 関係の場合、 QuerySet.update()を使用して更新が実行されます。 これには、オブジェクトがすでに保存されている必要があります。
bulk=False引数を使用して、代わりにe.save()を呼び出して、関連するマネージャーに更新を実行させることができます。ただし、多対多の関係で
add()を使用すると、save()メソッドは呼び出されず(bulk引数は存在しません)、を使用して関係が作成されます。 QuerySet.bulk_create()。 リレーションシップの作成時にカスタムロジックを実行する必要がある場合は、 m2m_changed シグナルをリッスンします。これにより、pre_addおよびpost_addアクションがトリガーされます。すでに存在するリレーションで
add()を使用しても、リレーションは複製されませんが、シグナルはトリガーされます。多対多の関係の場合、
add()は、*objs引数として、モデルインスタンスまたはフィールド値(通常は主キー)のいずれかを受け入れます。必要に応じて、
through_defaults引数を使用して、新しい中間モデルインスタンスの値を指定します。through_defaultsディクショナリの値として呼び出し可能オブジェクトを使用でき、中間インスタンスを作成する前に一度評価されます。バージョン3.1で変更:
through_defaults値を呼び出し可能にできるようになりました。
- create(through_defaults=None, **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に設定する必要があると判断しました。必要に応じて、
through_defaults引数を使用して、新しい中間モデルインスタンスの値を指定します。through_defaultsディクショナリの値として呼び出し可能オブジェクトを使用できます。バージョン3.1で変更:
through_defaults値を呼び出し可能にできるようになりました。
- remove(*objs, bulk=True)
指定されたモデルオブジェクトを関連オブジェクトセットから削除します。
>>> 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 シグナルをリッスンします。多対多の関係の場合、
remove()は、*objs引数として、モデルインスタンスまたはフィールド値(通常は主キー)のいずれかを受け入れます。ForeignKey オブジェクトの場合、このメソッドは
null=Trueの場合にのみ存在します。 関連フィールドをNone(NULL)に設定できない場合、オブジェクトを別のオブジェクトに追加せずにリレーションから削除することはできません。 上記の例では、b.entry_set()からeを削除することは、e.blog = Noneを実行することと同じであり、blogForeignKey にはnull=True、これは無効です。ForeignKey オブジェクトの場合、このメソッドは
bulk引数を受け入れて、操作の実行方法を制御します。True(デフォルト)の場合、QuerySet.update()が使用されます。bulk=Falseの場合、代わりに個々のモデルインスタンスのsave()メソッドが呼び出されます。 これにより、 pre_save および post_save 信号がトリガーされ、パフォーマンスが犠牲になります。多対多の関係の場合、
bulkキーワード引数は存在しません。
- clear(bulk=True)
関連するオブジェクトセットからすべてのオブジェクトを削除します。
>>> b = Blog.objects.get(id=1) >>> b.entry_set.clear()これは関連するオブジェクトを削除するのではなく、それらの関連付けを解除するだけであることに注意してください。
remove()と同様に、clear()は ForeignKey でのみ使用可能であり、null=Trueであり、bulkキーワード引数も受け入れます。多対多の関係の場合、
bulkキーワード引数は存在しません。
- set(objs, bulk=True, clear=False, through_defaults=None)
関連するオブジェクトのセットを置き換えます。
>>> new_list = [obj1, obj2, obj3] >>> e.related_set.set(new_list)このメソッドは、
clear引数を受け入れて、操作の実行方法を制御します。False(デフォルト)の場合、新しいセットから欠落している要素はremove()を使用して削除され、新しい要素のみが追加されます。clear=Trueの場合、代わりにclear()メソッドが呼び出され、セット全体が一度に追加されます。ForeignKey オブジェクトの場合、
bulk引数は add()および remove()に渡されます。多対多の関係の場合、
bulkキーワード引数は存在しません。set()は複合操作であるため、競合状態の影響を受けることに注意してください。 たとえば、clear()の呼び出しとadd()の呼び出しの間に新しいオブジェクトがデータベースに追加される場合があります。多対多の関係の場合、
set()は、objs引数として、モデルインスタンスまたはフィールド値(通常は主キー)のリストを受け入れます。必要に応じて、
through_defaults引数を使用して、新しい中間モデルインスタンスの値を指定します。through_defaultsディクショナリの値として呼び出し可能オブジェクトを使用でき、中間インスタンスを作成する前に一度評価されます。バージョン3.1で変更:
through_defaults値を呼び出し可能にできるようになりました。
ノート
add()、create()、remove()、clear()、およびset()はすべて、すべてのタイプの関連フィールドにデータベースの変更をすぐに適用することに注意してください。 つまり、関係の両端でsave()を呼び出す必要はありません。prefetch_related()を使用する場合、
add()、remove()、clear()、およびset()メソッドはプリフェッチされたキャッシュをクリアします。