2016-09-19 5 views
0

ここでは、古典的な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=Falseremove()に渡されるとどうなりますか? 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()に渡された同じオブジェクトで呼び出されないのはなぜですか?

答えて

1

新しい情報を得るには、データベースに戻る必要があります。 goudaオブジェクトはデータベース行へのリンクを自動的に保持しません。そうするように指示されたときにのみクエリを実行します。

関連する問題