| この記事の要点 |
|
基本
Article.objects.order_by("created_at") # 昇順(古い順)
Article.objects.order_by("-created_at") # 降順(新しい順)
# 複数キー: 点数の高い順、同点なら名前の五十音順
Article.objects.order_by("-score", "title")
# 発行される SQL
print(Article.objects.order_by("-created_at").query)
# SELECT ... FROM "blog_article" ORDER BY "blog_article"."created_at" DESC
マイナスはフィールド名の直前に付けます。order_by("created_at DESC") のように SQL のキーワードを書くと FieldError になります。
並び順を後から変える・消す
qs = Article.objects.filter(published=True)
qs = qs.order_by("-created_at") # 追加ではなく「置き換え」
qs = qs.order_by("title") # 前の指定は消え、title 順になる
qs.reverse() # 指定済みの並びを逆にする
qs.order_by() # 並び順をすべて解除する
order_by() は累積しません。2 回呼んだら後の指定だけが残ります。段階的に組み立てたい場合はリストにためて最後に一度だけ渡します。
order = []
if sort_by_score:
order.append("-score")
order.append("-created_at")
qs = Article.objects.order_by(*order)
モデルの既定の並び順
class Article(models.Model):
title = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_at"] # 何も指定しなければこの順
Meta.ordering を付けると、すべてのクエリに ORDER BY が付きます。件数が多いテーブルでは、意図しないソートが性能に効いてくることがあります。
集計と組み合わせるときは特に注意が必要です。
from django.db.models import Count
# Meta.ordering のフィールドが GROUP BY に混ざり、結果が分かれてしまう
Article.objects.values("author").annotate(n=Count("id"))
# 集計の前に並び順を解除する
Article.objects.order_by().values("author").annotate(n=Count("id"))
リレーション先で並べる
Article.objects.order_by("-author__age") # 著者の年齢の降順
Article.objects.order_by("author__name", "-score") # 著者名順、同著者内は点数降順
# JOIN が増えるので select_related と併用する
Article.objects.select_related("author").order_by("-author__age")
アンダースコア 2 個でリレーションをたどります。1 個だとフィールド名として解釈され FieldError: Cannot resolve keyword になります。
集計値・計算値で並べる
from django.db.models import Count, F, Value
from django.db.models.functions import Coalesce, Lower
# コメント数の多い順
Article.objects.annotate(n=Count("comments")).order_by("-n")
# 計算した値で並べる
Article.objects.annotate(rate=F("likes") * 100 / F("views")).order_by("-rate")
# 大文字小文字を無視して並べる
Article.objects.order_by(Lower("title"))
# NULL を 0 として扱う
Article.objects.order_by(Coalesce("score", Value(0)).desc())
NULL の位置を制御する
from django.db.models import F
Article.objects.order_by(F("published_at").desc(nulls_last=True))
Article.objects.order_by(F("published_at").asc(nulls_first=True))
| DB | 既定の NULL の位置(昇順) |
|---|---|
| PostgreSQL | 最後 |
| MySQL / MariaDB | 最初 |
| SQLite | 最初 |
開発が SQLite で本番が MySQL といった構成では、同じコードでも並びが変わります。nulls_last を明示すれば揃います。
ランダム・件数制限との組み合わせ
Article.objects.order_by("?")[:5] # ランダム 5 件(大量データでは重い)
Article.objects.order_by("-created_at")[:10] # 新着 10 件
Article.objects.order_by("-created_at")[10:20] # 11〜20 件目
Article.objects.latest("created_at") # 最も新しい 1 件
Article.objects.earliest("created_at") # 最も古い 1 件
スライスした後は order_by() や filter() を呼べません(Cannot filter a query once a slice has been taken.)。絞り込みと並べ替えを済ませてから最後にスライスします。件数制限の詳細は limit, offsetの指定方法 を参照してください。
大量データで遅いとき
class Article(models.Model):
created_at = models.DateTimeField(db_index=True) # 単一キー
class Meta:
indexes = [
models.Index(fields=["-created_at", "id"]), # 複合+降順
]
ORDER BY に使う列にインデックスが無いと、DB は毎回すべての行を並べ替えます。並び順とインデックスの順序を一致させるのが基本です。実際に効いているかは qs.explain() で確認できます(SQLのログ出力方法)。
関連
- データベースへの接続と操作 — 親カテゴリ
- filterの検索オプション
- limit, offsetの指定方法
- SELECT, INSERT, UPDATE, DELETE
- SQLのログ出力方法
- 素のSQLを直接実行する方法
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09