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

revision-up-to:17812 (1.4)
class RelatedManager

“Related manager” は一対多リレーションや多対多リレーションに関連して 使われます。以下 2 つの場合に登場します:

  • ForeignKey リレーションの「向こう側」。 つまり:

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

    上の例では、マネージャ reporter.article_set で後述のメソッドが使用可能 になります (訳注: ここでの reporterReporter のインスタンス です)。

  • ManyToManyField リレーションの「両側」:

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

    この例では、 topping.pizza_setpizza.toppings で後述のメソッド が使用可能になります (訳注: ここでの toppingTopping クラスの、 pizzaPizza クラスのインスタンスです) 。

これらの “related manager” はいくつか追加のメソッドを持っています:

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

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

使い方:

>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Entry e を Blog b に関連づけます。
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)
... )

# e は自動的に保存されるので、 e.save() は呼ばなくてかまいません

上の例は、下記と同じ処理を実現します:

>>> b = Blog.objects.get(id=1)
>>> e = Entry(
...      blog=b,
...      headline='Hello',
...      body_text='Hi',
...      pub_date=datetime.date(2005, 1, 1)
...  )
>>> e.save()

リレーションを定義するためのキーワード引数を指定する必要はないので注意 してください。上の例では、 create()blog パラメタを渡してい ません。 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.

データベースの一貫性を保持するために、このメソッドは null=TrueForeignKey オブジェクトでしか使えません。 リレーションフィールドの値を None (NULL) にできなければ、あるオブジェクトを 被リレーションセットから除去したときに、何らかの他のオブジェクトに対して リレーションを張り直さなければならないからです。上の例で、 b.entry_set() からの e の除去は e.blog = None に 相当しますが、 blogForeignKey には null=True が設定されていないので、これは無効な操作です。

clear()

被リレーションセットから、全てのオブジェクトを除去します:

>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()

このメソッドは、リレーション元のオブジェクトを削除せず、ただ単に リレーションを解除するだけなので注意してください。

remove() と同様、 clear()null=TrueForeignKey でしか使えません。