DjangoのORMで取得したデータを特定の順序で並び替えるには、order_by()メソッドを使用します。昇順・降順の指定や複数フィールドでの並び替えなど、柔軟なソート処理が可能です。
基本的な使い方
views.py
model = Company.objects.all().order_by('-pk')
説明
Step 1order_byメソッドの基本
Djangoでは、以下の形式でモデルのデータを並べ替えることができます:
モデル.objects.all().order_by('並べ替えに使用するフィールド')
モデル.objects.filter(条件).order_by('並べ替えに使用するフィールド')
これにより、指定したフィールドの値で昇順(小さい順)に並べ替えられます。
例:
# 名前の昇順(アルファベット順)に並べ替え
companies = Company.objects.all().order_by('name')
# idの昇順に並べ替え
companies = Company.objects.all().order_by('id')
Step 2降順での並べ替え
フィールド名の前に「-」(マイナス)を付けることで、降順(大きい順)に並べ替えることができます:
モデル.objects.all().order_by('-並べ替えに使用するフィールド')
例:
# IDの降順に並べ替え
companies = Company.objects.all().order_by('-id')
上の例では、pkが降順になるように並べ替えています。
Step 3複数フィールドでの並べ替え
複数のフィールドを指定して並べ替えることもできます:
モデル.objects.all().order_by('フィールド1', 'フィールド2')
この場合、最初に指定したフィールドで並べ替え、値が同じ場合は次のフィールドで並べ替えられます。
例:
# まず場所で昇順に並べ、同じ場所のデータはIDの降順に並べる
companies = Company.objects.all().order_by('location', '-id')
Step 4条件付き検索と並べ替えの組み合わせ
filterやexcludeなどの条件付き検索と組み合わせることができます:
# nameが「test」を含むデータをIDの降順で取得
companies = Company.objects.filter(name__contains='test').order_by('-id')
# 複数条件での検索結果を並べ替え
companies = Company.objects.filter(is_active=True).exclude(location='北海道').order_by('name')
Step 5ランダムな並べ替え
データをランダムに並べ替えたい場合は、?を使用します:
# ランダムに並べ替え
companies = Company.objects.all().order_by('?')
ただし、大量のデータがある場合はパフォーマンスに影響するため注意が必要です。
Step 6実践的な使用例
views.pyでのorder_byメソッドの使用例:
from django.shortcuts import render
from .models import Company
def company_list(request):
# ソートパラメータの取得(デフォルトは'name')
sort_by = request.GET.get('sort', 'name')
# ソート方向の取得(デフォルトは昇順)
direction = request.GET.get('direction', 'asc')
# ソート方向に基づいてフィールド名を調整
if direction == 'desc':
sort_field = f'-{sort_by}'
else:
sort_field = sort_by
# データを並べ替えて取得
companies = Company.objects.all().order_by(sort_field)
return render(request, 'companies/company_list.html', {
'companies': companies,
'current_sort': sort_by,
'current_direction': direction
})
テンプレートでの使用例(company_list.html):
<h1>会社一覧</h1>
<div class="sort-controls">
<p>並べ替え:</p>
<a href="?sort=name&direction=asc">名前(昇順)</a>
<a href="?sort=name&direction=desc">名前(降順)</a>
<a href="?sort=id&direction=asc">ID(昇順)</a>
<a href="?sort=id&direction=desc">ID(降順)</a>
</div>
<table>
<tr>
<th>ID</th>
<th>名前</th>
<th>アクション</th>
</tr>
{% for company in companies %}
<tr>
<td>{{ company.id }}</td>
<td>{{ company.name }}</td>
<td>
<a href="{% url 'company_detail' company.id %}">詳細</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="3">会社が登録されていません。</td>
</tr>
{% endfor %}
</table>
ポイント
注意点: デフォルトでは、DjangoはモデルのMetaクラスにorderingが定義されていない限り、データベースから返される順序が保証されません。そのため、一貫した結果を得るためには常にorder_byを使用することをお勧めします。
まとめ
order_by('フィールド名')で昇順に並び替えできるorder_by('-フィールド名')のようにマイナスを付けると降順になる- 複数フィールドを指定すると、優先順位を付けた並び替えが可能
order_by('?')でランダム順にできるが、パフォーマンスに注意- モデルの
Metaクラスでorderingを指定するとデフォルトの並び順を設定できる reverse()で並び順を反転させることもできる