revision-up-to: | 17812 (1.4) |
---|
“Related manager” は一対多リレーションや多対多リレーションに関連して 使われます。以下 2 つの場合に登場します:
ForeignKey
リレーションの「向こう側」。
つまり:
class Reporter(models.Model):
...
class Article(models.Model):
reporter = models.ForeignKey(Reporter)
上の例では、マネージャ reporter.article_set
で後述のメソッドが使用可能
になります (訳注: ここでの reporter
は Reporter
のインスタンス
です)。
ManyToManyField
リレーションの「両側」:
class Topping(models.Model):
...
class Pizza(models.Model):
toppings = models.ManyToManyField(Topping)
この例では、 topping.pizza_set
と pizza.toppings
で後述のメソッド
が使用可能になります (訳注: ここでの topping
は Topping
クラスの、
pizza
は Pizza
クラスのインスタンスです) 。
これらの “related manager” はいくつか追加のメソッドを持っています:
指定したモデルオブジェクトを、被リレーションのセットに追加し (リレーショ ン先のオブジェクトからリレーションを張り) ます。
使い方:
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.add(e) # Entry e を Blog b に関連づけます。
新たなオブジェクトを生成し、保存して、被リレーションのセットに追加しま す。新たに生成されたオブジェクトを返します:
>>> 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
をセットすべきだと自動的に理解します。
指定したオブジェクトを被リレーションセットから除去します:
>>> b = Blog.objects.get(id=1)
>>> e = Entry.objects.get(id=234)
>>> b.entry_set.remove(e) # Disassociates Entry e from Blog b.
データベースの一貫性を保持するために、このメソッドは null=True
の
ForeignKey
オブジェクトでしか使えません。
リレーションフィールドの値を
None
(NULL
) にできなければ、あるオブジェクトを
被リレーションセットから除去したときに、何らかの他のオブジェクトに対して
リレーションを張り直さなければならないからです。上の例で、
b.entry_set()
からの e
の除去は e.blog = None
に
相当しますが、 blog
の ForeignKey
には
null=True
が設定されていないので、これは無効な操作です。
被リレーションセットから、全てのオブジェクトを除去します:
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.clear()
このメソッドは、リレーション元のオブジェクトを削除せず、ただ単に リレーションを解除するだけなので注意してください。
remove()
と同様、 clear()
は null=True
の
ForeignKey
でしか使えません。
Oct 26, 2017