単一の条件指定
通常このように指定していると思います。
views.py
#QuerySetで返す
MyUser.objects.filter(name=query)
#ひとつだけ返す(確実にデータがある場合にのみgetは使う)
MyUser.objects.get(name=query)
#除外する
MyUser.objects.all().exclude(name=query)
複数の条件指定
andの場合
複数の条件全てを満たすものを取得する場合,
を使います。
views.py
#名前にtaroを含む20歳のユーザーを取得
MyUser.objects.filter(name__icontains="taro", age="20")
#名前がtaroで20歳のユーザーを取得
MyUser.objects.get(name="taro", age="20")
#名前にtaroを含む20歳のユーザーを除外
MyUser.objects.all().exclude(name__icontains="taro", age="20")
orの場合
条件を一つでも満たすものを取得する場合Q objects
と|
を使います。
views.py
from django.db.models import Q
#名前にtaroを含むか、20歳以下のユーザーを取得
MyUser.objects.filter( Q(name__icontains="taro")|Q(age__lte="20") )
#名前にtaroを含むか、20歳以下のユーザーを除外
MyUser.objects.all().exclude( Q(name__icontains="taro")|Q(age__lte="20") )
上記の場合、taroを含む全てのユーザーと、20歳以下の全てのユーザーが取得できます。
andとor両方使う場合
Q objects
とキーワード引数
を混在させる場合は、先にQ objects
を書くこと。
views.py
from django.db.models import Q
#Tokyo出身で、名前にtaroを含むか、20歳以下のユーザーを取得
MyUser.objects.filter(
Q(birthplace="Tokyo"), Q(name__icontains="taro")|Q(age__lte="20"))
#キーワード引数を使う場合
MyUser.objects.filter(
Q(name__icontains="taro")|Q(age__lte="20"), birthplace="Tokyo",)
#これだと無効になる
MyUser.objects.filter(
birthplace="Tokyo", Q(name__icontains="taro")|Q(age__lte="20"))
全てQ objectsにすれば順番は気にしないでOK!
先にキーワード引数を書くと無効になるので注意!
複数のQuerySetを結合する
複数のQuerySetを結合したい場合は|
を使う。
views.py
hoge1 = MyUser.objects.filter(hogehoge1)
hoge2 = MyUser.objects.filter(hogehoge2)
#hoge1と2のQuerySetを結合する
total_hoge = hoge1|hoge2
#QuerySetから本人を除外する
total_hoge = (hoge1|hoge2).exclude(id=request.user.id)
#重複を無くす(※注意)
total_hoge = (hoge1|hoge2).distinct()
重複についてshell
で確認したところ、hoge1|hoge2
の時点で重複が無くります。
なので、クエリが複数のテーブルにまたがっている場合など、何らかの理由で重複が発生した場合以外は使わないでOK!
というのも・・
distinctは注意
データベースの種類やorder.byの有無で機能しない場合があります。
PostgreSQL
とそれ以外で書き方が変わります。
詳しくは公式ページで確認してみてくださいまし!
演算子で結合
この方法は重複等色々手間が発生するで、上記の|
をオススメしますが一応紹介。
views.py
hoge1 = MyUser.objects.filter(hogehoge1)
hoge2 = MyUser.objects.filter(hogehoge2)
#hoge1と2のリスト化して結合する
total_hoge = list(hoge1) + list(hoge2)
#.excludeは使えないので結合する前に除外しておく
hoge1 = MyUser.objects.filter(hogehoge1).exclude(id=request.user.id)
hoge2 = MyUser.objects.filter(hogehoge2).exclude(id=request.user.id)
#本人を除外した
total_hoge = list(hoge1) + list(hoge2)
いや、もう演算子を使うのは色々と不便なので却下ですね笑
ちょっと助長でしたがこんな感じです!