ORM

Django ORMでデータの並び替え|order_by()の使い方

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()で並び順を反転させることもできる