DjangoのORMで条件に合うデータを複数取得するには、filter()メソッドを使用します。get()とは異なり、条件に合うすべてのレコードをQuerySetとして返すため、0件でもエラーになりません。ここでは、filter()の基本的な使い方とルックアップ(検索条件)を解説します。
基本的な使い方
views.py
model = Company.objects.filter(name='test');
print(model[0].name)
説明
Step 1filterメソッドの基本
Djangoでは、以下の形式で条件に一致するモデルの複数のデータを取得できます:
モデル.objects.filter(条件)
例えば、特定の名前を持つデータをすべて取得する場合:
companies = Company.objects.filter(name="test")
上の例ではCompanyモデルのnameがtestのデータを全て取得しています。
Step 2比較演算子の使用
条件を以上、以下などとしたいときは、以下のように記入します:
- 大きい:
フィールド名__gt=比べる値 - 以上:
フィールド名__gte=比べる値 - 以下:
フィールド名__lte=比べる値 - 未満:
フィールド名__lt=比べる値
例:
# idが10以上の会社を取得 companies = Company.objects.filter(id__gte=10) # idが20未満の会社を取得 companies = Company.objects.filter(id__lt=20)
Step 3部分一致検索
部分的に一致したデータを取得したいときは、以下のように記入します:
- 対象の値を含む:
フィールド名__contains=値 - 対象の値を含む(大文字、小文字の区別なし):
フィールド名__icontains=値 - 大文字、小文字を区別しない完全一致:
フィールド名__iexact=値
例:
# 名前に「株式会社」を含む会社を取得 companies = Company.objects.filter(name__contains="株式会社") # 名前に「test」を含む会社を取得(大文字小文字を区別しない) companies = Company.objects.filter(name__icontains="test")
Step 4複数条件の組み合わせ
filterメソッドでは、複数の条件を指定してフィルタリングできます:
# 複数条件をカンマで区切って指定(AND条件) companies = Company.objects.filter(name="test", id=5)
カンマで区切られた複数の条件は「AND」条件として扱われ、すべての条件に一致するモデルのみが取得されます。
Step 5フィルタリング結果へのアクセス
filterメソッドの結果はクエリセット(QuerySet)と呼ばれるリスト形式のオブジェクトとなります。データにアクセスするには、以下の形式で記入します:
モデルを代入した変数[インデックス].フィールド名
例:
companies = Company.objects.filter(name__contains="テスト")
# 最初の会社の名前にアクセス
first_company_name = companies[0].name
# すべての会社名を表示
for company in companies:
print(company.name)
ポイント
注意: インデックスがリストの範囲外の場合(例えば空のクエリセットで[0]にアクセスしようとする場合)、IndexErrorが発生します。そのため、アクセス前に結果が空でないか確認することが推奨されます。
Step 6追加のフィルタリングオプション
基本的なフィルタリングオプション:
# 特定のIDリストに含まれる会社を取得 companies = Company.objects.filter(id__in=[1, 3, 5]) # 名前が「テスト」で始まる会社を取得 companies = Company.objects.filter(name__startswith="テスト") # 名前が「株式会社」で終わる会社を取得 companies = Company.objects.filter(name__endswith="株式会社")
まとめ
filter()メソッドで条件に合う複数のデータをQuerySetとして取得できる- 条件に合うデータがない場合は空のQuerySetが返る(エラーにならない)
__exact,__contains,__gteなどのルックアップで柔軟な検索ができる- 複数の条件を指定するとAND条件になる
filter()はチェーン可能で、段階的に条件を追加できる- QuerySetは遅延評価されるため、実際にデータを使用するまでSQLは実行されない