djangoのquerysetを任意の順番でsortする
djangoのquerysetを任意の順番でsortする
djnagoではorder_by('hoge')
とするとhogeの昇順でならんでいくことは当たり前のように知っているよね。
が、ぼくがやりたかったのは、任意の値でのソート。
databaseに定義されてない値でソートしたかったのです。
とても参考になったstack overflowはこちら。
Django order_by specific order - Stack Overflow
ただし
django >= 1.8
です
TL;DR
from djnago.db.models import Case, When, Value, FloatField
# { pid: specific_value, }
specific_values = {
'1': 100.0,
'2': 50.0,
'3': 25.0,
'4': 123.4,
'5': 599.33,
}
# sqlのCASE式にしたい条件のリスト
cases = []
# casesにCASE式にしたい条件をつめていく
for pid, specific_value in specific_values.items():
cases.append(When(id=pid, then=Value(specific_value)))
# Hogeモデルに対して、pidで絞り込んだあとにcasesをつかってspecific_valueについて注釈づけてorder_byする
Hoge.objects.filter(id__in=specific_values.keys()).annotate(specific_value=Case(
*cases,
output_field=FloatField()
)).order_by(specific_value)
詳しい説明
Conditional Expressions | Django documentation | Django
TIPS
- casesに条件をつめこむため、
Case
インスタンスを作成する際に、*
で展開してあげないといけない。
ここだけ気をつければ非常に便利(使い所があまりないのが玉に瑕)。