クエリを作成する | Django ドキュメント | Django
データベースからオブジェクトを取得するには、モデルクラスの Manager から QuerySet を作ります。
各モデルは少なくとも一つの Manager を持ち、デフォルトでは objects という名前を持ちます。
SQL 文においては、 QuerySet は SELECT 句、フィルターは WHERE や LIMIT のような絞り込みに用いる句に対応しています。
特定のオブジェクトの取得
Entry.objects.all()
filter() 一致するもの
exclude() 一致しないもの
それぞれメソッドチェーンもできる。
getは条件のデータが存在しない場合、2つ以上マッチした場合は例外を発生する(DoesNotExist, MultipleObjectReturned)
filter()[0]でスライスした場合は、IndexErrorとなる
指定がない場合exactでマッチされる。
iexactは大文字小文字を判別しない。
contains部分一致
リレーションを横断
model__field='zzz'
データがなかった場合、リレーションがなかったのか、値がなかったのか判別できない
pk
ぜんぶ同じ
id_exact=1
id=1
pk=1
F()
クエリの中でモデルフィールドを参照するときに使う
演算も対応。
Entry.objects.filter(number_of_comments__gt=F('field_name') * 2)
アンダースコア2つで連結して、関連モデルのデータを参照できる
F('blog__name')
時間の計算もできる
F('pub_date') + timedelta(days=3)
LIKE
下記のLIKEが使われるクエリでは、%と_はSQLではエスケープされる
iexact, contains, icontains, startswith, istartswith, endswith and iendswith
クエリのキャッシュ
QuerySetはデータベースアクセスを最小限にするために内部キャッシュを持つ
QuerySetを変数に格納しておくと、評価する際にキャッシュが使われる。
queryset = Entry.objects.all() # 一旦格納
QuerySetの一部しか評価されなかった場合、キャッシュは使われない。
全体を一度評価した場合は、その後キャッシュが使われる。
いきなり queryset[5] をするとキャッシュが使われないが、一旦全部取得した後実行するとキャッシュが使われる。
[entry for entry in queryset] # 全てにアクセス
JSONFieldの検索
Noneを指定するとSQLのNULLが格納される。JSONとしてのnullはValue('null')を使う。
検索も同様にSQLのNULLはisnullを使う。
JSON内部の値を検索するにはダブルアンダースコアでチェーンする。
配列にはインデックス番号が指定できる。
データベース製品による挙動の違いに注意。
Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
その他のメソッド
contained_by、has_key、has_keys、has_any_keys
Qオブジェクトを使った複雑な検索
from django.db.models import Q
Q オブジェクトは & や | 演算子を使って結合することができます
Poll.objects.get(
Q(question__startswith='Who'),
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
SELECT * from polls WHERE question LIKE 'Who%'
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
オブジェクトの比較
イコールを使ったオブジェクト同士の比較はプライマリーキーの比較と同等である。
オブジェクトのコピー
組み込みのコピー機能は無いが、pkをNoneにして保存すると新たなpkが生成されるのでコピーと同等である。
blog.pk = None
blog.save()
一括更新
更新できるのはメインのテーブルのみ。関連テーブルは更新できない。
リレーションの外部キーの更新はできるので、関連データのインスタンスを渡す。
F()を使ったフィールドの指定ができるが、joinは使えないので同一テーブルのみ。
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
関連オブジェクト
関連オブジェクトがある場合のアクセスは、単純に外部キー指定されているフィールドを指定する。
反対に関連オブジェクト側から元のオブジェクトのmanagerにアクセス出来る。
名前xxx_setとなりモデル名は小文字となる。
ForeignKey定義時にrelated_nameオプションを指定している場合、xxx_setはそれで上書きされる。
独自のmanagerを使う場合はmanagerオプションに指定する。
entry_set(manager='entries')
メソッド
add, create, remove, clear, set