# Django 5.2.8 ドキュメント

# リレーション先オブジェクトのリファレンス

class RelatedManager

  "関係マネージャ（related manager）"とは、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)
  aadd(*objs, bulk=True, through_defaults=None)

    非同期バージョン: `aadd()`

    リレーション先オブジェクトのセットに、指定したモデルオブジェクトを追加します。

    例:

        >>> 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` シグナルを待ち受けます。

    すでに存在するリレーションに `add()` を使っても、リレーションは複製されませんが、シグナルは発生します。

    多対多のリレーションシップの場合、 `add()` は `*objs` 引数としてモデルインスタンスかフィールドの値（通常は主キー）を受け付けます。

    必要であれば、引数 `through_defaults` を使用して、新しい 中間モデル インスタンスの値を指定します。呼び出し可能オブジェクトを `through_defaults` 辞書の値として使用することができ、中間インスタンスを作成する前に一度だけ評価されます。

  create(through_defaults=None, **kwargs)
  acreate(through_defaults=None, **kwargs)

    非同期バージョン: `acreate()`

    新しいオブジェクトを作成して保存し、リレーション先オブジェクトのセットに入れます。新しく作成されたオブジェクトを返します:

        >>> 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)

    リレーションシップを定義するモデルのキーワード引数を指定する必要はないことに注意してください。上の例では、 `create()` にパラメータ `blog` を渡していません。Django は新しい `Entry` オブジェクトの `blog` フィールドを `b` に設定すべきであると判断します。

    必要であれば、 `through_defaults` 引数を使用して、新しい 中間モデル インスタンスの値を指定します。呼び出し可能オブジェクトを `through_defaults` 辞書の値として使用できます。

  remove(*objs, bulk=True)
  aremove(*objs, bulk=True)

    非同期バージョン: `aremove()`

    リレーション先オブジェクトのセットから指定されたモデルオブジェクトを削除します:

        >>> b = Blog.objects.get(id=1)
        >>> e = Entry.objects.get(id=234)
        >>> b.entry_set.remove(e)  # Disassociates Entry e from Blog b.

    Similar to `add()`, `e.save()` is called in the example above to perform the update. Using `remove()` with a many-to-many relationship, however, will delete the relationships using `QuerySet.delete()` which means no model `save()` methods are called; listen to the `m2m_changed` signal if you wish to execute custom code when a relationship is deleted.

    多対多のリレーションシップの場合、 `remove()` は `*objs` 引数としてモデルインスタンスかフィールドの値（通常は主キー）を受け付けます。

    `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` シグナルをトリガーします。

    多対多のリレーションシップの場合、キーワード引数 `bulk` は存在しません。

  clear(bulk=True)
  aclear(bulk=True)

    非同期バージョン: `aclear()`

    リレーション先オブジェクトのセットからすべてのオブジェクトを削除します:

        >>> 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)
  aset(objs, bulk=True, clear=False, through_defaults=None)

    非同期バージョン: `aset()`

    リレーション先のオブジェクトのセットを置き換えます:

        >>> 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` 辞書の値として使用することができ、中間インスタンスを作成する前に一度だけ評価されます。

  注釈

  `add()`, `aadd()`, `create()`, `acreate()`, `remove()`, `aremove()`, `clear()`, `aclear()`, `set()`, そして `aset()` はすべて、すべてのタイプのリレーション先のフィールドに対してデータベースの変更を即座に適用することに注意してください。つまり、リレーションシップのどちらの側でも `save()`/`asave()` を呼び出す必要はありません。

  `prefetch_related()` を使用すると、 `add()`, `aadd()`, `remove()`, `aremove()`, `clear()`, `aclear()`, `set()`, `aset()` メソッドがプリフェッチキャッシュをクリアします。