ここでは、古典的なDjangoのブログとエントリモデルをドキュメント(link)から使用します。エントリーのブログ属性にnull=True
を追加しました。Django - Understanding RelatedManagerメソッドを削除する
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> cb.entry_set.remove(gouda)
>>> gouda.blog
<Blog: Cheese blog>
私はすべてがうまく、データベースに更新されていることを、私は再び私の例から2番目の行を問い合わせる場合gouda.blog
つもりリターンNone
ですが、私の質問は、なぜNone
は、別のクエリなしgouda.blog
ではないされていることを知っていますか?
EDIT:
私はすべてを正しく理解してあれば、これはそれがどのように動作するかです:
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> cb.entry_set.remove(gouda)
>>> gouda.blog
<Blog: Cheese blog>
のでremove()
方法についてbulk
引数のデフォルト値はTrue
です。つまり、QuerySet.update()
が使用されます。オブジェクトgouda
はPythonレベルでは変更されないので、blog
属性は "Cheese blog"ブログの主キーを保持します。 gouda.blog
を照会すると、「Cheese blog」オブジェクトが取得されます。
bulk=False
がremove()
に渡されるとどうなりますか? documentationから:bulk = Falseの場合は、代わりにそれぞれのモデルインスタンスのsave()メソッドが呼び出されます。
それでは私はこのようなEntry
モデルのsave()
方法オーバーライドします。その後、
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if self.blog == None:
print(id(self))
をして:
>>> cb = Blog.objects.get(name__startswith="Cheese")
>>> gouda = Entry.objects.get(headline__startswith="Gouda")
>>> cb.entry_set.all()
[<Entry: Gouda>, <Entry: Emmentaler>]
>>> id(gouda)
139797518743592
>>> cb.entry_set.remove(gouda, bulk=False)
139797518745552
>>> gouda.blog
<Blog: Cheese blog>
は、今、私たちはsave()
メソッドがコールされていることをgouda
オブジェクトが同じでないことを確認私たちのシェルのものとして、シェル内のオブジェクトはまだblog
属性に "Cheese blog"の主キーを保持しています。 gouda.blog
でブログを検索すると、まだ「Cheese blog」オブジェクトが取得されています。
それが正しいのですが、save()
は、remove()
に渡された同じオブジェクトで呼び出されないのはなぜですか?