LoginSignup
0
0

More than 1 year has passed since last update.

Djangoのクエリセットの評価タイミング

Posted at

クエリセットの評価タイミングで、正しくない動作をしていたコードを修正したので、メモです。

ダメだったコード

ダメ
def update():
    update_user_ids = Users.object.filter(status=True).values_list('id').all()
    update_count = Users.object.filter(status=True).update(status=Fasle)
    
   return update_count, update_user_ids

この関数では、updateしたuserのidとその件数を返すものです。

しかし、実際に更新したupdate_countupdate_user_idsの件数が異なっていました。(update_user_idsは空の配列)

クエリセットの評価タイミング

update_user_ids = Users.object.filter(status=True).values_list('id').all()

この時点では、update_user_idsにクエリセットが構築されただけで、実際にDBへのアクセスは行われていません。
クエリが実行されるのは、実際の値が必要になったタイミングです。(遅延評価というみたい)

update前の結果を代入したつもりですが、実際には評価されておらず、update後に評価されると対象はすでに存在せず、空の配列が返っていました。

正しい
def update():
    update_user_ids = list(Users.object.filter(status=True).values_list('id').all())
    update_count = Users.object.filter(status=True).update(status=Fasle)
    
   return update_count, update_user_ids

list()にすることで評価されて、update前の値を取得します。

(この記事書いていて思ったのですが、return update_user_ids, update_countの返り値の順番を入れ替えてもできるのでは・・・)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0