Djangoのモデルでのフィールドルックアップ
DjangoのモデルでQuerySetのフィールドルックアップ
すぐに忘れてしまうので、モデルを利用したクエリ処理をを備忘録としてまとめておく
フィールドルックアップ
フィールドルックアップは、SQLのWHERE句の内容を指定する手段です。filter() 、 exclude() および get() にキーワード引数として指定します。
基本のルックアップキーワード引数は「カラム名__lookuptype=value」で指定します
ルックアップタイプ
以下のようなルックアップタイプがあります
キーワード | 説明 |
---|---|
exact | 完全一致、アルファベットの大文字と小文字を区別する |
iexact | 完全一致、アルファベットの大文字と小文字を区別しない |
contains | 部分一致、アルファベットの大文字と小文字を区別する |
icontains | 部分一致、アルファベットの大文字と小文字を区別しない |
startswith | 前方一致、アルファベットの大文字と小文字を区別する |
istartswith | 前方一致、アルファベットの大文字と小文字を区別しない |
endswith | 後方一致、アルファベットの大文字と小文字を区別する |
iendswith | 後方一致、アルファベットの大文字と小文字を区別しない |
in | いずれかに一致、指定されたイテラブル(多くの場合、リスト、タプル、クエリセット)内に含まれるかをチェックします。あまり使われませんが、(イテラブルである)文字列は使用可能です |
gt | より大きい |
gte | 以上 |
lt | より小さい |
lte | 以下 |
range | 範囲のチェック(~~を含む)、range は SQL で BETWEEN が使えるところならどこでも使えます。日付、数字、そして文字でも使えます |
regex | 正規表現、アルファベットの大文字と小文字を区別する |
iregex | 正規表現、アルファベットの大文字と小文字を区別しない |
isnull | "True" または "False" を受け取り、それぞれ IS NULL と IS NOT NULL の SQL クエリに対応します |
date | datetimeフィールドの値を date としてキャストします。追加のフィールドルックアップを連結できます。date値を取ります |
year | 日付フィールドとdatetimeフィールドにおける、"年" の完全一致。追加のフィールドルックアップを連結できます。年を整数で指定します |
month | 日付フィールドおよびdatetimeフィールドにおける、"月" の完全一致。追加のフィールドルックアップを連結できます。1 (1月) から 12 (12月) までの整数を指定します |
day | 日付フィールドとdatetimeフィールドにおける、"日" の完全一致。追加のフィールドルックアップを連結できます。日を整数で指定します |
week | 日付フィールドおよびdatetimeフィールドにおける、 ISO-8601 に従った週番号 (1~52または53) を返します。すなわち、週は月曜日から始まり、最初の週にはその年の最初の木曜日が含まれます |
week_day | 日付フィールドとdatetimeフィールドにおける "曜日" の一致。追加のフィールドルックアップを連結できます。1 (日曜日) から 7 (土曜日) までの曜日を表す整数値を指定します |
hour | datetimeフィールドとtimeフィールドにおける、"時(hour)" の完全一致。追加のフィールドルックアップを連結できます。0 から 23 までの整数を指定します |
minute | datetime フィールドと time フィールドにおける、"分" の完全一致。追加のフィールドルックアップを連結できます。0 から 59 までの整数を指定します |
second | datetime および time フィールドにおける、"秒" の完全一致。追加のフィールドルックアップを連結できます。0 から 59 までの整数を指定します |
exact
nameがFireDragonと完全一致
exactをつけなくても自動的にexactになる。デフォルトでexactと同じ意味になる
Monster.objects.filter(name__exact="FireDragon")
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` = 'FireDragon'
contains
nameにDragonが含まれる
含まれるかどうかの判定を行う
Monster.objects.filter(name__contains="Dragon")
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` LIKE BINARY '%Dragon%'
startswith
nameがDarkから始まる
前方一致を検索します
Monster.objects.filter(name__startswith="Dark")
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` LIKE BINARY 'Dark%'
endswith
nameがDragonで終わる
後方一致を検索します
Monster.objects.filter(name__endswith="Dragon")
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` LIKE BINARY '%Dragon'
in
いずれかに一致します。値にはイテラブル、つまり、リストなどを指定します。リスト、タプルなどが指定可能です。文字列も指定可能
リストに一致する
リストの要素に一致するデータを選択します。一致しないデータが含まれていてもOK
Monster.objects.filter(name__in=["FireDragon","Slime","XXX"])
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` IN ('FireDragon', 'Slime', 'XXX')
数値のリスト
Monster.objects.filter(hp__in=[40,60,80,100])
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`hp` IN (40, 60, 80, 100)
文字列で可能
利用パターンは少ないが文字列でも可能
Monster.objects.filter(name__in="abc")
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`name` IN ('a', 'b', 'c')
gt, gte
hpが40より大きい
Monster.objects.filter(hp__gt=40)
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`hp` > 40
lt, lte
mpが80より小さい
Monster.objects.filter(mp__lt=80)
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`mp` < 80
range
range は SQL で BETWEEN が使えるところならどこでも使えます。日付、数字、そして文字でも使えます。値をタプルで2個指定します
hpが40から80
Monster.objects.filter(hp__range=(40,80))
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`hp` BETWEEN 40 AND 80
date
datetime フィールドの値を date としてキャストします。追加のフィールドルックアップを連結できます。 date 値を取ります
created_atが2020-08-10と等しい
datetimeフィールドに対して年月日を指定して検索します。一致したデータを取り出します。dateフィールドでは機能しない
# created_atはDatetime
import datetime
Monster.objects.filter(created_at__date=datetime.date(2020,8,10))
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
DATE(CONVERT_TZ(`monster`.`created_at`, 'UTC', 'Asia/Tokyo')) = '2020-08-10'
dateフィールドの場合、dateを利用しないで実現可能
# birthdayはDateフィールド
Monster.objects.filter(birthday=datetime.date(2000,5,12))
create_atが指定日より未来
dateとgteを併用して指定日より未来を検索します
Monster.objects.filter(created_at__date__gte=datetime.date(2021,4,1))
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
DATE(CONVERT_TZ(`monster`.`created_at`, 'UTC', 'Asia/Tokyo')) >= '2021-04-01'
year
日付フィールドとdatetimeフィールドにおける、"年" の完全一致。追加のフィールドルックアップを連結できます。年を整数で指定します
年が等しい
Monster.objects.filter(birthday__year=2001)
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
`monster`.`birthday`
BETWEEN
'2001-01-01' AND '2001-12-31'
month
日付フィールドおよびdatetimeフィールドにおける、"月" の完全一致。追加のフィールドルックアップを連結できます。1 (1月) から 12 (12月) までの整数を指定します
月が等しい
Monster.objects.filter(birthday__month=5)
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
EXTRACT(MONTH FROM `monster`.`birthday`) = 5
day
日付フィールドおよびdatetimeフィールドにおける、 ISO-8601 に従った週番号 (1~52または53) を返します。すなわち、週は月曜日から始まり、最初の週にはその年の最初の木曜日が含まれます
日が等しい
Monster.objects.filter(birthday__day=20)
SELECT
`monster`.`id`,
`monster`.`name`,
`monster`.`hp`,
`monster`.`mp`,
`monster`.`type`,
`monster`.`birthday`
FROM
`monster`
WHERE
EXTRACT(DAY FROM `monster`.`birthday`) = 20
Discussion