revision-up-to: | 17812 (1.4) unfinished |
---|
このドキュメントでは、 クエリセット(QuerySet
) API について詳しく解説し
ます。このドキュメントは、 モデル と
データベースクエリ に基づいて書かれているので、
あらかじめ読んでおくよう勧めます。
このリファレンスを通じて、例題には データベースクエリガイド で取り上げた ブログのモデル例 を使います。
内部的には、クエリセットの生成、フィルタ操作、スライス、コード間の受渡しは、 データベースを操作することなく行えます。クエリセットを何らかの形で評価しな い限り、データベースの操作は実際には起こらないのです。
以下の方法を使うと、クエリセットを評価できます:
イテレーション。 クエリセットはイテレーション可能オブジェクトであ り、オブジェクトに対して最初にイテレーション操作を行ったときにデータ ベースクエリを実行します。例えば、以下の例はデータベース中の全てのエ ントリのヘッドラインを出力します:
for e in Entry.objects.all():
print e.headline
QuerySet
をスライスすると通常は新しい未評価の QuerySet
を返しますが、スライス表記に「ステップ (step)」パラメタを使った場合は、
データベースクエリを実行してリストを返します。(部分的または完全に) 評価した
QuerySet
をスライスした場合も、リストを返します。Pickle 化 / キャッシュ。 QuerySets を pickle する 時にどう関わってくるのか、詳しくは後述します。 この章の趣旨的に重要なのは、結果はデータベースから読み出されるということです。
repr(). クエリセットに対して repr()
を呼び出すと、クエリセッ
トは値評価されます。これは Python 対話インタプリタでの利便性のための
仕様で、 API を対話的に使うときに結果を即座に見られるようにしています。
len(). クエリセットに対して len()
を呼び出すと、クエリセッ
トは値評価されます。予想に違わず、 len()
はクエリ結果リストの長さ
を返します。
注意: クエリセット中のレコードの数を知りたいだけなら、 len()
は
使わないでください 。レコード数の計算はデータベース上で SQL 文の
SELECT COUNT(*)
使って行う方が遥かに効率的であり、まさにその理由
から Django では count()
メソッドを提供しています。後述の
count()
を参照してください。
list(). クエリセットに対して list()
を呼び出すと、値評価を強
制できます。例えば:
entry_list = list(Entry.objects.all())
とはいえ、この方法を使うと、Django が全ての要素のリストをメモリ上にロー ドするため、巨大なメモリオーバヘッドを引き起こす可能性があるので十分 注意してください。これに対し、クエリセットに対するイテレーション操作 では、必要な分だけデータをロードしてオブジェクトをインスタンス化する という利点があります。
bool()。 bool() の使用時や if 文での使用時など、真理値として QuerySet を評価すると、クエリーが実行されます。もし一つ以上の結果が得られた場合、 QuerySet は真 (True) と評価され、さもなければ偽 (False) と評価されます。 たとえば:
if Entry.objects.filter(headline="Test"):
print "There is at least one Entry with the headline Test"
Note: もし一つ以上の結果が存在するかどうかを知りたいだけで、
実際のオブジェクトが必要無いのであれば、この方法は 使わないでください 。
exists()
を使った方がもっと効率的です
(後述します)。
If you pickle
a QuerySet
, this will force all the results to be loaded
into memory prior to pickling. Pickling is usually used as a precursor to
caching and when the cached queryset is reloaded, you want the results to
already be present and ready for use (reading from the database can take some
time, defeating the purpose of caching). This means that when you unpickle a
QuerySet
, it contains the results at the moment it was pickled, rather
than the results that are currently in the database.
If you only want to pickle the necessary information to recreate the
QuerySet
from the database at a later time, pickle the query
attribute
of the QuerySet
. You can then recreate the original QuerySet
(without
any results loaded) using some code like this:
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
The query
attribute is an opaque object. It represents the internals of
the query construction and is not part of the public API. However, it is safe
(and fully supported) to pickle and unpickle the attribute’s contents as
described here.
通常は手動で作成しないものではありますが (Manager
を通して作成するでしょうから)、 QuerySet
の正式な宣言は以下の通りです:
QuerySet
([model=None, query=None, using=None])¶通常、クエリセットを操作するときには、 フィルタを連鎖 させます。クエリセットに対するフィルタ操作は、 ほとんどが新たなクエリセットを返します。これらのメソッドの詳細は後述します。
QuerySet
クラスには状態の分析 (introspection) に使える公開された属性が
2 つあります:
ordered
¶QuerySet
が整列済みであれば True
になります — つまり、
order_by()
節またはデフォルト整列順序の指定がモデルにあれば
True
になります。さもなければ False
になります。
db
¶そのクエリーを、その時点で実行した場合に使われるデータベースです。
Note
QuerySet
の query
パラメータが存在しているのは
GeoQuerySet
などの特殊な
クエリーを行うサブクラスが内部的なクエリーの状態を再構築できるように
するためです。パラメータの値はクエリーの素 (opaque) の表現であり、
公開 API の一部ではありません。簡単に言うと:
これについて質問するくらいであれば使う必要はありません。
Django は、クエリセットの返す結果の形式や、 SQL クエリの実行方法を変更する ためのリファインメソッドを幅広く提供しています。
filter
(**kwargs)¶指定の照合パラメタに一致するオブジェクトの入った新たなクエリセットを返しま す。
照合パラメタ (**kwargs
) は後述の フィールドの照合 で説明するフォーマッ
トにします。複数のパラメタを指定すると、背後の SQL 文では AND
で結合さ
れます。
exclude
(**kwargs)¶指定の照合パラメタに一致 しない オブジェクトの入った新たなクエリセットを 返します。
照合パラメタ (**kwargs
) は後述の フィールドの照合 で説明するフォーマッ
トにします。複数のパラメタを指定すると、背後の SQL 文では AND
で結合さ
れ、制約条件節全体を NOT()
で囲みます。
以下の例では、 pub_date
が 2005 年 1 月 3 日より未来の日時になっていて、
かつ headline
が “Hello” で始まる全てのエントリを除外します:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
SQL では以下のようなクエリの評価と同じです:
SELECT ...
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
また、以下の例では、 pub_date
が 2005 年 1 月 3 日より未来の日時で
あるか、 または headline
が “Hello” で始まる全てのエントリを除外しま
す:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')
SQL では以下のようなクエリの評価と同じです:
SELECT ...
WHERE NOT pub_date > '2005-1-3'
AND NOT headline = 'Hello'
二つ目の例の方が制約が厳しいことに注意して下さい。
annotate
(*args, **kwargs)¶QuerySet
中の各オブジェクトを、クエリーに関係するオブジェクトを集計
(aggregate) した値 (平均値や合計値など) のリストでアノテート (annotate)
します。 annotate()
の各引数は、返される QuerySet
中のオブジェクトに
追加されるアノテーションです。
django が提供する集計関数については Aggregation Functions で後述します。
キーワード引数を使って指定したアノテーションは、そのキーワードをアノテーション の別名として使用します。無名の引数で指定した場合は、集計関数の名前と 集計対象モデルフィールドの名前を元に別名が生成されます。
たとえばブログのリストを操作しているとすると、各ブログに何個のエントリーが 作られているのか知りたいと思うかもしれません:
>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42
Blog
モデル自体は entry__count
属性を定義していません。しかし集計関数
の指定にキーワード引数を使うことでアノテーションの名前を変えられます:
>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# The number of entries on the first blog, using the name provided
>>> q[0].number_of_entries
42
集計に関する深い議論については 集計のトピックガイド を参照してください。
order_by
(*fields)¶デフォルトでは、 QuerySet
の返す結果はモデルの Meta
の ordering
オプションに指定した整列条件のタプルに従って整列されます。 order_by
を
使うと、この挙動を QuerySet
単位でオーバライドできます。
例えば:
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
このクエリを実行すると、検索結果はまず pub_date
で降順に並べられ、次い
で headline
で昇順に並べられます。 "-pub_date"
の先頭にあるマイナス
記号が 降順 を表しています。何も指定しないと昇順です。整列をランダムにし
たければ、以下のように ”?” を使います:
Entry.objects.order_by('?')
注意: order_by('?')
を使うと、使っているバックエンドによってはコストの
かかる低速なクエリを実行してしまいます。
別のモデル内のフィールドを使ってモデルを整列させるには、モデルのリレーショ
ン追跡と同じ構文を使ってフィールドを指定します。すなわち、フィールド名の後
ろにアンダースコア 2 つ (__
) 、さらに新たなモデルのフィールド名を続けま
す。この調子で、任意の深さまでモデルを追跡できます。例えば:
Entry.objects.order_by('blog__name', 'headline')
他のモデルへのリレーションを使ってモデルインスタンスを整列しようとすると、
Django はリレーション先のモデルのデフォルトの整列順 (Meta.ordering
が指定されていなければプライマリキー)
を使います。例えば:
Entry.objects.order_by('blog')
は、 Blog
モデルにデフォルトの整列順が指定されていないので、以下のコー
ドと同じです:
Entry.objects.order_by('blog__id')
リレーション先のモデルのフィールドを使った整列と distinct()
を組み合わせる場合は注意が必要です。リレーション先のモデルの整列が、
どのような影響を受けるかは、 distinct()
の説明を参照してください。
クエリ結果の整列には、 (ManyToManyField
のような)
複数の値で構成されるフィールドも指定できます。通常、こうした指定には
あまり意味がなく、本当に高度な使い方です。しかし、クエリセットを
フィルタした結果や、もともとのデータにおいて、リレーション元のオブジェクトから
参照しているオブジェクトが一つしかないことが暗黙的に決まっていると
はっきりしていれば、整列結果は期待通りになるでしょう。複数の値で構成される
フィールドで整列を行う場合には、十分注意して、期待通りの結果が得られるか
確認してください。
大小文字の区別を考慮して整列するかどうかを指定する方法はありません。大小文 字の区別については、 Django は現在使っているデータベースバックエンドの整列 方法に従います。
もしデフォルトの並び順すらも含めて整列させたくない場合、パラメータを付けずに
order_by()
を呼んでください。
QuerySet.ordered
属性を確認すればクエリーが整列されているかどうか
判定できます。この属性は、どのような整列方法であっても、整列されていれば
True
になります。
reverse
()¶クエリセットに要素を逆順に返させたいときは reverse()
メソッドを使ってく
ださい。 reverse()
を 2 回呼ぶと、並び順を通常に戻します。
ところでクエリセットの「末尾の」 5 つの要素を取り出す場合、以下のように書け ます:
my_queryset.reverse()[:5]
これは、 Python で起きる末尾部分のスライスと完全には同じでないので注意しま
しょう。上の例の場合、要素を、末尾から順に返します。 Python で
seq[-5:]
のようにした場合、末尾から 5 番目を最初に返します。 SQL で効率
的に表現する方法がないので、 Django は このやり方 (末尾からのスライス) をサ
ポートしていません。
また、 reverse()
は一般に、すでに整列方法の定義されているクエリセット
(デフォルトの整列順の定義されたモデルから取り出したクエリセットや、
order_by()
で整列されたもの) に対して呼びだすべきものです。整列方法の定
義されていないクエリセットに対して reverse()
を呼び出しても、何ら効果
をもたらしません (reverse()
を呼び出す前に整列方法が定義されていなけれ
ば、呼び出した後の整列方法も未定義のままです)。
distinct
([*fields])¶SQL クエリに SELECT DISTINCT
を使う新たな QuerySet
を返します。
distinct()
を使うと、クエリ結果から重複する行をなくします。
デフォルトでは、 QuerySet
は重複する行を除去しません。通常は、
Blog.objects.all()
のような単純なクエリは重複する行を含むような結果にな
らないため、これはあまり問題ではありません。しかし、クエリが複数のテーブル
にわたる場合、 QuerySet
の評価結果に重複する結果が入る場合があります。
その場合には distinct()
を使って下さい。
Note
order_by()
に指定したフィールドは、 SQL レベルで SELECT
されます。そのため、 order_by()
と distinct()
と組み合わせると
予期しない結果を生むことがあります。例えば、リレーション先のモデルフィー
ルドを使って整列を行うと、それらのフィールドも SELECT
されるため、
リレーション元のオブジェクトは同じ値で、リレーション先のフィールド値だ
けが違うレコードは異なる (distinct) レコードとみなされます。リレーショ
ン先のレコードカラムは (順序を制御するために使われるだけなので) 返され
ず、その結果、distinct 制約を満たしていないクエリ結果が返されるように見
えてしまいます。
同様に、 values()
クエリを使って SELECT
対象のカラムを制約する
場合も、 order_by()
に指定したカラム (またはモデルのデフォルトの順
序制御カラム) が自動的にクエリ結果に含められ、結果の一意性に影響を及ぼ
します。
distinct()
を使う場合、リレーション先のフィールドを使った並べ替えに
はよく注意しましょう。同様に、 distinct()
と values()
を同時に
使うときにも、 values()
の対象とするフィールドに順序カラムが入って
いない場合はよく注意してください。
リリースノートを参照してください
Django 1.4 以降では、 DISTINCT
が適用されるべきフィールド名を位置指定引数
(*fields
) で指定できます。これは SQL クエリーの SELECT DISTINCT ON
に変換されます。
違いを説明します。通常の distinct()
の呼び出しでは、データベースは
どの行が異なる (distinct) のかを判断するために各行の 全フィールドを 比較します。
フィールド名を指定した distinct()
の呼び出しでは、データベースは指定された
フィールド名だけを比較します。
Note
このフィールド名を指定する機能は PostgreSQL でのみ利用可能です。
Note
フィールド名を指定する場合、 order_by()
を QuerySet に指定する
必要 (must) があり、また order_by()
に指定するフィールド群は
distinct()
に指定するフィールド群で始まっている (順番も同じ)
必要があります。
たとえば、 SELECT DISTINCT ON (a)
は列 a
の値それぞれについて、
その値が最初に現れる行を取得します。
If you don’t specify an order, you’ll get some arbitrary row.
Examples:
>>> Author.objects.distinct()
[...]
>>> Entry.objects.order_by('pub_date').distinct('pub_date')
[...]
>>> Entry.objects.order_by('blog').distinct('blog')
[...]
>>> Entry.objects.order_by('author', 'pub_date').distinct('author', 'pub_date')
[...]
>>> Entry.objects.order_by('blog__name', 'mod_date').distinct('blog__name', 'mod_date')
[...]
>>> Entry.objects.order_by('author', 'pub_date').distinct('author')
[...]
values
(*fields)¶ValueQuerySet
を返します。 ValueQuerySet
は QuerySet
のサブクラ
スで、評価結果としてモデルインスタンスオブジェクトの代りに辞書のリストを返
す QuerySet
です。
リスト中の各辞書は個々のオブジェクトを表現しており、キーがモデルオブジェク トの各属性名に、対応しています。
以下の例では、 values()
の辞書と通常のモデルオブジェクトを比較していま
す:
# Blog オブジェクトのリストを返します。
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]
# 辞書のリストを返します。
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]
values()
メソッドはオプションの可変長の引数 *fields
を取れます。
このオプションは SELECT
の制限に使うフィールド名を列挙したものです。
fields
を指定した場合、辞書には指定した名前のフィールドのキーと
値だけが入ります。 *fields
を指定しなければ、辞書にはテーブルの全ての
フィールドのキーと値が入ります。
例を示します:
>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]
注意すべき点がいくつかあります:
ForeignKey
foo
がモデルに入っている場
合、 values()
がデフォルトで返す辞書には、 foo_id
というキー
が入ります。これは、リレーションの実際の値が入っているモデル内部の隠
しフィールドの名前です (foo
はリレーション先のモデルインスタンス
への参照です)。一方、 values()
にフィールド名を指定して呼び出す
場合は、 foo
と foo_id
のどちらでも渡せますが、得られる結果は
同じ (辞書のキーは渡したフィールド名と同じ) で、リレーションの実際の
値です。
例を以下に示します:
>>> Entry.objects.values()
[{'blog_id': 1, 'headline': u'First Entry', ...}, ...]
>>> Entry.objects.values('blog')
[{'blog': 1}, ...]
>>> Entry.objects.values('blog_id')
[{'blog_id': 1}, ...]
values()
と distinct()
を組み合わせて使う場合、カラム値による
並べ替えが結果に思わぬ影響をもたらすことがあります。詳しくは
distinct()
の節を参照してください。
extra()
の呼び出し後に values()
を使う場合、 extra()
の select
引数で定義されるフィールドすべてを明示的に values()
の呼び出し時に指定する必要があります。 values()
の呼び出し後に
extra()
を呼び出した場合、 select で追加されるフィールドは
無視されます。ValuesQuerySet
が便利なのは、わずかな数のフィールドの値しか必要でなく、
モデルインスタンスオブジェクトの機能が必要でないと分かっている場合です。
必要なフィールドだけを選択すると、さらに効率的です。
最後に、 ValuesQuerySet
は QuerySet
のサブクラスなので、
QuerySet
の全てのメソッドを持っている点に注意してください。
ValuesQuerySet
に対して filter()
や order_by()
といった操作を行
えます。つまり、以下の二つの呼び出しは等価です:
Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()
Django の作者たちは、全ての SQL 関係のメソッドを先に配置し、その後に (必要
なら) 出力関係のメソッド (values()
など) を配置するやり方を好んでいます。
とはいえ、これは実際上問題ではないので、個人的な信条を反映させてかまいませ
ん。
リリースノートを参照してください
以前は values()
メソッドに ManyToManyField
属性を渡すと、何も返されず、エラーが送出されました。
この制限は無くなり、 OneToOneField
、 ForeignKey
そして
ManyToManyField
属性を通して関係したモデルのフィールドを参照することも
可能になりました:
Blog.objects.values('name', 'entry__headline')
[{'name': 'My blog', 'entry__headline': 'An entry'},
{'name': 'My blog', 'entry__headline': 'Another entry'}, ...]
Warning
ManyToManyField
属性と逆引きのリレーションは複数
の行を持つ可能性があるので、これらを含めると結果セットのサイズが増えること
があります。これはそのようなフィールドを values()
クエリーに複数含めると、
すべての組み合わせが返されるため、特に顕著になります。
values_list
(*fields)¶values()
に似ていますが、辞書を返す代わりに、イテレーション時にタプルを
返します。各タプルには values_list()
の引数に渡したフィールドの値が、
引数の順番に一致して入っています。例えば:
>>> Entry.objects.values_list('id', 'headline')
[(1, u'First entry'), ...]
フィールドを一つだけ指定する場合、 flat
というパラメタも指定できます。
このパラメタを True
にすると、結果は 1 要素のタプルではなく一つの値とし
て返されます。以下の例を見れば、違いがはっきりするでしょう:
>>> Entry.objects.values_list('id').order_by('id')
[(1,), (2,), (3,), ...]
>>> Entry.objects.values_list('id', flat=True).order_by('id')
[1, 2, 3, ...]
複数のフィールドを指定しているときに flat
を渡すとエラーを送出します。
values_list()
に引数を渡さなければ、モデルの全てのフィールドを定義順に
並べたタプルのリストを返します。
dates
(field, kind, order='ASC')¶DateQuerySet
を返します。 DateQuerySet
は QuerySet
のサブクラス
で、評価結果としてクエリセット内のコンテンツの全日付を
datetime.datetime
オブジェクトとして返します。
field
はモデルの DateField
または DateTimeField
の名前です。
kind
は "year"
, "month"
または "day"
です。
結果リスト中の各 datetime.datetime
オブジェクトは type
の指定に従っ
て切り詰められます。
"year"
を指定すると、フィールドの年部分の値の重複しないリストを返します。"month"
を指定すると、フィールドの年/月部分の値の重複しないリストを
返します。"day"
を指定すると、フィールドの年/月/日部分の値の重複しないリストを
返します。order
には結果の並び順を指定します。デフォルト値は 'ASC'
で、
"ASC"
または "DESC"
にできます。
例を示します:
>>> Entry.objects.dates('pub_date', 'year')
[datetime.datetime(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.datetime(2005, 3, 20)]
Warning
タイムゾーンサポートが有効化されていると Django はデータベース接続で UTC を使うので、集計は UTC にて行われます。 これは、現在の実装における既知の制限事項です。
none
()¶EmptyQuerySet
を返します。 EmptyQuerySet
とは、評価結果が常に空の
リストである QuerySet
のサブクラスです。関数の戻り値などで空の照合結果を
返したいけれども、呼び出し側が (空のリストなどではなく) クエリセットオブジェクト
の戻り値を期待しているような場合に便利です。
例:
>>> Entry.objects.none()
[]
all
()¶クエリセット(またはそのサブクラス)の コピー を返します。モデルマネジャや
クエリセットを引数に渡してフィルタ処理を行わせたいような場合に便利です。
モデルマネジャもクエリセットも all()
を呼び出して、適切なクエリセットを
取り出せるからです。
extra
(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)¶時として、 Django のクエリ表記法だけでは複雑な WHERE
節を容易に表現でき
ない場合があります。こうした特異な場合のために、 Django では extra()
というクエリセット修飾子を提供しています。このメソッドは、クエリセットが
生成する SQL 文中に特定の SQL 節を挿入するためのフックです。
定義上、これらの拡張照合機能は (直接 SQL コードを書いているため) データベー スエンジン間の可搬性がありません。また、 DRY 則の侵犯でもあります。可能な限 り使わないようにして下さい。
params
, select
, where
, tables
のいずれかを指定します。
いずれの引数も必須ではありませんが、少なくとも一つは指定せねばなりません。
select
select
キーワードを使うと、 SELECT
節に追加のフィールドを選択で
きます。この引数は、属性名とその属性値を計算するための SQL 節を対応づけ
た辞書にします。
例えば:
Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
のようにすると、 Entry
オブジェクトは、エントリの pub_date
が
Jan. 1, 2006 より大きいかどうかを示すブール値の属性 is_recent
を
持つようになります。
Django は指定された SQL を直接 SELECT
文に挿入するので、上の例の
SQL 文は以下のようになります:
SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
FROM blog_entry;
次の例はもっと高度です。この例では、 Blog
オブジェクトに関連づけら
れている Entry
オブジェクトの個数を表す整数を、 Blog
オブジェク
トの entry_count
属性に持たせるためにサブクエリを実行しています:
Blog.objects.extra(
select={
'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
},
)
上の場合では、クエリの FROM
節に blog_blog
が入るという事実を
利用しています。
上の例の場合、 SQL は以下のようになります:
SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id)
FROM blog_blog;
ほとんどのデータベースエンジンでは、サブセレクションの周りに丸括弧が必
要ですが、Django の select
節では必要ないということに注意してくださ
い。また、 MySQL の一部のバージョンのように、データベースバックエンドに
よってはサブクエリをサポートしないので注意してください。
ごく稀に、 extra(select=...)
に指定する SQL にパラメタを渡したい場
場合があります。そんなときは select_params
パラメタを使ってください。
ただし、 select_params
はシーケンス型で、 select
は辞書なので、
select=
の中でパラメタが正しく一致するように注意する必要があります。
select
に通常の辞書型を渡す代わりに
django.utils.datastructures.SortedDict
を指定すれば、こうした状況を
うまく扱えます。
例えば、以下のコードは期待通りに動作します:
Blog.objects.extra(
select=SortedDict([('a', '%s'), ('b', '%s')]),
select_params=('one', 'two'))
extra()
に SELECT パラメタを渡す時には、 "%%s"
(s
の前のパー
セント記号が 二重 のもの) だけは使わないでください。 Django は
%s
を探してパラメタの挿入位置を追跡しますが、 "%%s"
のように
%
がエスケープされていると検出しないからです。そのため、クエリ結果
が正しくなくなります。
where
/ tables
明示的に追加の WHERE
節を渡す必要がある場合 – おそらく非明示的な結
合を行っている場合 – には、 where
キーワードを使って下さい。
tables
を使えば、 SQL の FROM
節に手動でテーブル名を追加できま
す。
where
や tables
は、ともに文字列のリストを引数にとります。
where
パラメタの内容は全て、多の検索条件と “AND” で結合されます。
例えば:
Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
は、(大雑把にいって) 以下のような SQL 文に変換されます:
SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);
tables
パラメタを使う場合、クエリ中にすでに登場しているテーブルを指
定していないか注意が必要です。 tables
パラメタに追加のテーブル名を
指定して、それがすでにクエリ中に含まれているテーブルであった場合、
Django はユーザがそのテーブルをさらに加えようとしているものとみなします。
その場合、追加されたテーブルの名前にはエイリアスがつけられるので、問題
を引き起こします。 SQL 文の中に同じテーブルを複数回登場させる場合、デー
タベースがそれぞれのテーブルを区別できるように、2度目以降のテーブル名に
はエイリアスをつけねばなりません。そのため、 where
パラメタにすでに
クエリ中に存在するテーブル名を渡すと、エラーを引き起こすのです。
通常は、すでにクエリ中に存在するテーブル名を追加するような作業はしない
はずです。しかし、上で述べたようなことが起きてしまう場合には、いくつか
解決方法があります。まず、追加でテーブル名を指定しなくても正しくクエリ
を実行できるか試してください。それがだめなら、クエリセットを構築する際
に、 extra()
を先に呼び出して、テーブル名を最初に登場させてみてく
ださい。最後に、どうしてもうまくいかないのなら、生成されるクエリを見て、
where
を書き直し、テーブル名にエイリアスを与えてみてください。
エイリアスは同じ方法でクエリセットを生成している限り同じ名前を持つので、
エイリアス名は変化しないものとして扱えます。
order_by
クエリセットの評価結果を、 extra()
に入れたフィールドやテーブルに基
づいて並べ替えたい場合は、 extra()
に order_by
パラメタを指定し
てください。 order_by
は文字列のシーケンスで指定します。各文字列は
(order_by()
メソッドで指定するような) モデルフィールド名か、
table_name.column_name
形式か、 extra()
の select
パラメ
タに指定したカラムのエイリアスのいずれかで指定します。
例を示しましょう:
q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
q = q.extra(order_by = ['-is_recent'])
上の例は、 is_recent
が真であるような結果を先に表示します (True
よりも False
が先にくるのは降順のときだからです)。
ちなみに、上の例でわかるように、 extra()
は何度も呼び出しできます。
(その度に、制約条件が追加されてゆきます)。
params
上で説明した where
パラメタでは、標準の Python の文字列プレースホル
ダ '%s'
を使って、データベースエンジンが自動的にパラメタをクオート
するよう指示できます。 params
引数には、プレースホルダで置き換えら
れるパラメタのリストを指定します。
例えば:
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
where
の中に直接値を埋め込まず、常に params
を使うようにしてく
ださい。というのも、 params
を使えば、バックエンド固有の方法でパラ
メタの値を正しくクオートするからです。 例えば引用符文字などを正しくエ
スケープします。
悪い例:
Entry.objects.extra(where=["headline='Lennon'"])
良い例:
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
defer
(*fields)¶In some complex data-modeling situations, your models might contain a lot of fields, some of which could contain a lot of data (for example, text fields), or require expensive processing to convert them to Python objects. If you are using the results of a queryset in some situation where you know you don’t know if you need those particular fields when you initially fetch the data, you can tell Django not to retrieve them from the database.
This is done by passing the names of the fields to not load to defer()
:
Entry.objects.defer("headline", "body")
A queryset that has deferred fields will still return model instances. Each deferred field will be retrieved from the database if you access that field (one at a time, not all the deferred fields at once).
You can make multiple calls to defer()
. Each call adds new fields to the
deferred set:
# Defers both the body and headline fields.
Entry.objects.defer("body").filter(rating=5).defer("headline")
The order in which fields are added to the deferred set does not matter.
Calling defer()
with a field name that has already been deferred is
harmless (the field will still be deferred).
You can defer loading of fields in related models (if the related models are
loading via select_related()
) by using the standard double-underscore
notation to separate related fields:
Blog.objects.select_related().defer("entry__headline", "entry__body")
If you want to clear the set of deferred fields, pass None
as a parameter
to defer()
:
# Load all fields immediately.
my_queryset.defer(None)
Some fields in a model won’t be deferred, even if you ask for them. You can
never defer the loading of the primary key. If you are using
select_related()
to retrieve related models, you shouldn’t defer the
loading of the field that connects from the primary model to the related one
(at the moment, that doesn’t raise an error, but it will eventually).
Note
The defer()
method (and its cousin, only()
, below) are only for
advanced use-cases. They provide an optimization for when you have analyzed
your queries closely and understand exactly what information you need and
have measured that the difference between returning the fields you need and
the full set of fields for the model will be significant.
Even if you think you are in the advanced use-case situation, only use
defer() when you cannot, at queryset load time, determine if you will need
the extra fields or not. If you are frequently loading and using a
particular subset of your data, the best choice you can make is to
normalize your models and put the non-loaded data into a separate model
(and database table). If the columns must stay in the one table for some
reason, create a model with Meta.managed = False
(see the
managed attribute
documentation)
containing just the fields you normally need to load and use that where you
might otherwise call defer()
. This makes your code more explicit to the
reader, is slightly faster and consumes a little less memory in the Python
process.
only
(*fields)¶The only()
method is more or less the opposite of defer()
. You call
it with the fields that should not be deferred when retrieving a model. If
you have a model where almost all the fields need to be deferred, using
only()
to specify the complementary set of fields can result in simpler
code.
Suppose you have a model with fields name
, age
and biography
. The
following two querysets are the same, in terms of deferred fields:
Person.objects.defer("age", "biography")
Person.objects.only("name")
Whenever you call only()
it replaces the set of fields to load
immediately. The method’s name is mnemonic: only those fields are loaded
immediately; the remainder are deferred. Thus, successive calls to only()
result in only the final fields being considered:
# This will defer all fields except the headline.
Entry.objects.only("body", "rating").only("headline")
Since defer()
acts incrementally (adding fields to the deferred list), you
can combine calls to only()
and defer()
and things will behave
logically:
# Final result is that everything except "headline" is deferred.
Entry.objects.only("headline", "body").defer("body")
# Final result loads headline and body immediately (only() replaces any
# existing set of fields).
Entry.objects.defer("body").only("headline", "body")
All of the cautions in the note for the defer()
documentation apply to
only()
as well. Use it cautiously and only after exhausting your other
options.
using
(alias)¶リリースノートを参照してください
This method is for controlling which database the QuerySet
will be
evaluated against if you are using more than one database. The only argument
this method takes is the alias of a database, as defined in
DATABASES
.
For example:
# queries the database with the 'default' alias.
>>> Entry.objects.all()
# queries the database with the 'backup' alias
>>> Entry.objects.using('backup')
select_for_update
(nowait=False)¶リリースノートを参照してください
Returns a queryset that will lock rows until the end of the transaction,
generating a SELECT ... FOR UPDATE
SQL statement on supported databases.
For example:
entries = Entry.objects.select_for_update().filter(author=request.user)
All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.
Usually, if another transaction has already acquired a lock on one of the
selected rows, the query will block until the lock is released. If this is
not the behavior you want, call select_for_update(nowait=True)
. This will
make the call non-blocking. If a conflicting lock is already acquired by
another transaction, DatabaseError
will be raised when the
queryset is evaluated.
Note that using select_for_update()
will cause the current transaction to be
considered dirty, if under transaction management. This is to ensure that
Django issues a COMMIT
or ROLLBACK
, releasing any locks held by the
SELECT FOR UPDATE
.
Currently, the postgresql_psycopg2
, oracle
, and mysql
database
backends support select_for_update()
. However, MySQL has no support for the
nowait
argument. Obviously, users of external third-party backends should
check with their backend’s documentation for specifics in those cases.
Passing nowait=True
to select_for_update
using database backends that
do not support nowait
, such as MySQL, will cause a
DatabaseError
to be raised. This is in order to prevent code
unexpectedly blocking.
Using select_for_update
on backends which do not support
SELECT ... FOR UPDATE
(such as SQLite) will have no effect.
以下のクエリセットメソッドは、クエリセットを評価して、クエリセット でない 値を返します。
これらのメソッドはキャッシュを使わず (後述の キャッシュとクエリセット を参照してください)、メソッド呼び出しごとにデータベースにクエリをかけます。
get
(**kwargs)¶照合パラメタに一致するオブジェクトを返します。照合パラメタは後述の フィールドの照合 で説明するフォーマットにします。
複数のオブジェクトがみつかると、 get()
は
MultipleObjectsReturned
を送出します。The
MultipleObjectsReturned
exception is an
attribute of the model class.
指定パラメタに対するオブジェクトが見つからなかった場合には get()
は
DoesNotExist
例外を送出します。この例外は
モデルクラスの属性の一つです。例えば:
Entry.objects.get(id='foo') # raises Entry.DoesNotExist
DoesNotExist
例外は
django.core.exceptions.ObjectDoesNotExist
を継承しているので、
複数の DoesNotExist
例外を
except:
のターゲットにできます。例えば:
from django.core.exceptions import ObjectDoesNotExist
try:
e = Entry.objects.get(id=3)
b = Blog.objects.get(id=1)
except ObjectDoesNotExist:
print "Either the entry or blog doesn't exist."
create
(**kwargs)¶ワンステップでオブジェクトを生成して保存するための便宜メソッドです。 すなわち、以下の文:
p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
と、以下の文:
p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)
は等価です。
force_insert パラメタはここでは説明してい
ませんが、このパラメタを指定すると、常に新たなオブジェクトを生成します。
通常は、このパラメタのことを気にする必要はありません。しかし、モデルに手動
で設定した主キーが存在していて、すでにデータベース上にある主キーと同じ値を
もったオブジェクトを create()
して保存しようとすると、主キーの一意性が
破れてしまうため、 IntegrityError
を引き起こしてしまいます。
ですから、手動で主キーを設定したときには、例外処理を準備しておいてください。
get_or_create
(**kwargs)¶kwargs に指定したオブジェクトを照合し、なければ生成するための便宜メソッドで す。
(object, created)
の形式のタプルを返します。 object
は取得または作
成されたオブジェクトであり、 created
はブール値で、オブジェクトが新たに
生成されたかどうかを示します。
このメソッドは、お決まりのコードを書く上でのショートカットとして定義されて おり、データを取り込むスクリプトを書くときに便利です。例えば:
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
このようなコードパターンでは、モデル中のフィールドが増えると手に負えなくな
ります。 get_or_create()
を使うと、上のコード例は以下のように書き直せま
す:
obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
defaults={'birthday': date(1940, 10, 9)})
get_or_create()
に渡されたキーワード引数は、 (オプションの引数である
defaults
を除いて) 全て get()
の呼び出し時の引数として渡されます。
オブジェクトが見つかった場合、 get_or_create()
は見つかったオブジェクト
と False
を返します。オブジェクトが 見つからなかった 場合、新たに生成
されたオブジェクトと True
を返します。新たなオブジェクトは以下のアルゴ
リズムで作成されます:
defaults = kwargs.pop('defaults', {})
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
params.update(defaults)
obj = self.model(**params)
obj.save()
上のコードを日本語で表すなら、まず 'defaults'
でないキーワード引数のう
ち、二重アンダースコアを含まないもの (二重アンダースコアはあいまい照合のキー
ワードなので除外します) を使ってパラメタ params
を作成し、必要に応じて
デフォルト値 defaults
で内容を更新して、その結果をモデルクラスを呼び出
すときのキーワード引数に使う、という処理に相当します。上で示唆したように、
ここではアルゴリズムを簡単化して、必要な部分だけを記述しています。内部実装
では、もっと細かくエラーチェックを行い、境界条件を処理しています。興味があ
るなら、ぜひコードを読んでみてください。
defaults
という名前のフィールド名を持っていて、 get_or_create()
の
中で厳密照合に使いたければ、以下のように 'defaults__exact'
を使います:
Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})
主キーを手動で指定している場合、 get_or_create()
メソッドは
create()
と同じようなエラーを引き起こします。すなわち、すでにデータベー
ス上に存在するキーを使ってオブジェクトを生成しようとすると、
IntegrityError
を送出します。
最後に、 Django ビューの中で get_or_create()
を使う場合についてひとこと
注意しておきましょう。上で説明したように、主として get_or_create()
が有
用なのは、データを解析し、該当する既存のデータが存在しない場合に新たなレコー
ドを生成するようなスクリプトを書く場合です。ビューで get_or_create()
を
使いたいのなら、特に理由のない限り POST
リクエスト中で使うようにしましょ
う。一般論として、 GET
リクエストの処理中ではデータに影響を及ぼすべきで
はありません。データに副作用をもたらすようなページのリクエストには常に
POST
を使うようにしましょう。詳しくは、 HTTP 仕様における
安全なメソッド を参照してください。
bulk_create
(objs)¶リリースノートを参照してください
This method inserts the provided list of objects into the database in an efficient manner (generally only 1 query, no matter how many objects there are):
>>> Entry.objects.bulk_create([
... Entry(headline="Django 1.0 Released"),
... Entry(headline="Django 1.1 Announced"),
... Entry(headline="Breaking: Django is awesome")
... ])
This has a number of caveats though:
save()
method will not be called, and the pre_save
and
post_save
signals will not be sent.AutoField
it
does not retrieve and set the primary key attribute, as save()
does.Limits of SQLite
SQLite sets a limit on the number of parameters per SQL statement. The maximum is defined by the SQLITE_MAX_VARIABLE_NUMBER compilation option, which defaults to 999. For instance, if your model has 8 fields (including the primary key), you cannot create more than 999 // 8 = 124 instances at a time. If you exceed this limit, you’ll get an exception:
django.db.utils.DatabaseError: too many SQL variables
If your application’s performance requirements exceed SQLite’s limits, you should switch to another database engine, such as PostgreSQL.
count()
¶count
()¶クエリセットに一致するデータベース上のオブジェクトの個数を表す整数を返しま
す。 count()
メソッドは例外を送出しません。
例えば:
# データベース中のエントリの総数を返します。
Entry.objects.count()
# ヘッドラインが 'Lennon' を含むエントリの総数を返します。
Entry.objects.filter(headline__contains='Lennon').count()
count()
の呼び出しは背後で SELECT COUNT(*)
を実行するので、
単にオブジェクトの個数を数えたい場合には、全てのレコードを Python
オブジェクトとしてロードしてから len()
を呼び出すのではなく、常に
count()
を使うようにしてください。
(PostgreSQL や MySQL といった) どのデータベースを使っているかによって、
count()
の戻り値が Python の通常の整数型ではなく、長整数になることもあ
ります。これは実装上の問題であり、現実的に問題になることはありません。
in_bulk
(id_list)¶主キーの値のリストを引数にとり、各主キー値とオブジェクトを対応づけた辞書を 返します。
例えば:
>>> Blog.objects.in_bulk([1])
{1: <Blog: Beatles Blog>}
>>> Blog.objects.in_bulk([1, 2])
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>}
>>> Blog.objects.in_bulk([])
{}
in_bulk()
に空のリストを渡すと空の辞書を返します。
iterator
()¶QuerySet
を評価し (クエリを実行し) て、その結果の入ったイテレータ
(PEP 234 を参照してください) を返します。A QuerySet
typically caches its
results internally so that repeated evaluations do not result in additional
queries. In contrast, iterator()
will read results directly, without doing
any caching at the QuerySet
level (internally, the default iterator calls
iterator()
and caches the return value). For a QuerySet
which returns a
large number of objects that you only need to access once, this can results in
better performance and a significant reduction in memory.
すでに値にアクセス済みの QuerySet
に対して iterator()
を呼び出すと、
値の評価が再度行われ、クエリが繰り返し発行されるので注意してください。
Also, use of iterator()
causes previous prefetch_related()
calls to be
ignored since these two optimizations do not make sense together.
latest
(field_name=None)¶日付フィールドである field_name
の値に応じて、テーブル中の最新のオブジェ
クトを返します。
以下の例では、 pub_date
フィールドに応じて、テーブル中の最新の
Entry
を返します:
Entry.objects.latest('pub_date')
モデルの Meta で
get_latest_by
を指定している場合、
latest()
の field_name
引数は省略できます。 Django は
get_latest_by
に指定したフィールドを
デフォルト値にします。
get()
と同様、 latest()
は指定パラメタに一致するオブジェクトがない
場合に DoesNotExist
を送出します。
latest()
は純粋に利便性と可読性のためだけに存在しています。
aggregate
(*args, **kwargs)¶Returns a dictionary of aggregate values (averages, sums, etc) calculated
over the QuerySet
. Each argument to aggregate()
specifies
a value that will be included in the dictionary that is returned.
The aggregation functions that are provided by Django are described in Aggregation Functions below.
Aggregates specified using keyword arguments will use the keyword as the name for the annotation. Anonymous arguments will have an name generated for them based upon the name of the aggregate function and the model field that is being aggregated.
For example, when you are working with blog entries, you may want to know the number of authors that have contributed blog entries:
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}
By using a keyword argument to specify the aggregate function, you can control the name of the aggregation value that is returned:
>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}
For an in-depth discussion of aggregation, see the topic guide on Aggregation.
exists
()¶リリースノートを参照してください
Returns True
if the QuerySet
contains any results, and False
if not. This tries to perform the query in the simplest and fastest way
possible, but it does execute nearly the same query. This means that calling
QuerySet.exists()
is faster than bool(some_query_set)
, but not by
a large degree. If some_query_set
has not yet been evaluated, but you know
that it will be at some point, then using some_query_set.exists()
will do
more overall work (one query for the existence check plus an extra one to later
retrieve the results) than simply using bool(some_query_set)
, which
retrieves the results and then checks if any were returned.
update
(**kwargs)¶Performs an SQL update query for the specified fields, and returns the number of rows affected.
For example, to turn comments off for all blog entries published in 2010, you could do this:
>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
(This assumes your Entry
model has fields pub_date
and comments_on
.)
You can update multiple fields — there’s no limit on how many. For example,
here we update the comments_on
and headline
fields:
>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')
The update()
method is applied instantly, and the only restriction on the
QuerySet
that is updated is that it can only update columns in the
model’s main table, not on related models. You can’t do this, for example:
>>> Entry.objects.update(blog__name='foo') # Won't work!
Filtering based on related fields is still possible, though:
>>> Entry.objects.filter(blog__id=1).update(comments_on=True)
You cannot call update()
on a QuerySet
that has had a slice taken
or can otherwise no longer be filtered.
The update()
method returns the number of affected rows:
>>> Entry.objects.filter(id=64).update(comments_on=True)
1
>>> Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True)
0
>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
132
If you’re just updating a record and don’t need to do anything with the model
object, the most efficient approach is to call update()
, rather than
loading the model object into memory. For example, instead of doing this:
e = Entry.objects.get(id=10)
e.comments_on = False
e.save()
...do this:
Entry.objects.filter(id=10).update(comments_on=False)
Using update()
also prevents a race condition wherein something might
change in your database in the short period of time between loading the object
and calling save()
.
Finally, realize that update()
does an update at the SQL level and, thus,
does not call any save()
methods on your models, nor does it emit the
pre_save
or
post_save
signals (which are a consequence of
calling Model.save()
). If you want to
update a bunch of records for a model that has a custom
save()`()
method, loop over them and call
save()
, like this:
for e in Entry.objects.filter(pub_date__year=2010):
e.comments_on = False
e.save()
delete
()¶Performs an SQL delete query on all rows in the QuerySet
. The
delete()
is applied instantly. You cannot call delete()
on a
QuerySet
that has had a slice taken or can otherwise no longer be
filtered.
For example, to delete all the entries in a particular blog:
>>> b = Blog.objects.get(pk=1)
# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
By default, Django’s ForeignKey
emulates the SQL
constraint ON DELETE CASCADE
— in other words, any objects with foreign
keys pointing at the objects to be deleted will be deleted along with them.
For example:
blogs = Blog.objects.all()
# This will delete all Blogs and all of their Entry objects.
blogs.delete()
on_delete
argument to the
ForeignKey
.The delete()
method does a bulk delete and does not call any delete()
methods on your models. It does, however, emit the
pre_delete
and
post_delete
signals for all deleted objects
(including cascaded deletions).
フィールドの照合操作によって、 SQL の WHERE
節の中身が決まります。
フィールドの照合を行うには、 filter()
, exclude()
および
get()
といったクエリセットのメソッドのキーワード引数を指定します。
For an introduction, see models and database queries documentation.
厳密な一致です、比較対象の値を None
にすると、SQL における NULL
と
の比較として扱われます (詳しくは isnull
を参照してください)。
使い方の例を示します:
Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)
これは、以下の SQL と等価です:
SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;
大小文字の区別をしない一致です。
使い方の例を示します:
Blog.objects.get(name__iexact='beatles blog')
これは、以下の SQL と等価です:
SELECT ... WHERE name ILIKE 'beatles blog';
この例は、 'Beatles Blog'
, 'beatles blog'
, 'BeAtLes BLoG'
などにマッチします。
SQLite users
When using the SQLite backend and Unicode (non-ASCII) strings, bear in mind the database note about string comparisons. SQLite does not do case-insensitive matching for Unicode strings.
大小文字を区別する包含テストです。
使い方の例を示します:
Entry.objects.get(headline__contains='Lennon')
これは、以下の SQL と等価です:
SELECT ... WHERE headline LIKE '%Lennon%';
この例では、 'Lennon honored today'
というヘッドラインには一致しますが、
'lennon honored today'
には一致しません。
SQLite users
SQLite は大小文字を区別する LIKE
をサポートしないので、 contains
は
icontains
と同じになります。See the database note for more information.
大小文字を区別しない包含テストです。
使い方の例を示します:
Entry.objects.get(headline__icontains='Lennon')
これは、以下の SQL と等価です:
SELECT ... WHERE headline ILIKE '%Lennon%';
SQLite users
When using the SQLite backend and Unicode (non-ASCII) strings, bear in mind the database note about string comparisons.
指定のリストに入っているものに一致します。
使い方の例を示します:
Entry.objects.filter(id__in=[1, 3, 4])
これは、以下の SQL と等価です:
SELECT ... WHERE id IN (1, 3, 4);
リテラル値のリストを渡す代わりに、クエリセットを使って動的なリストとして評 価してもかまいません:
q = Blog.objects.filter(name__contains='Cheddar').values('pk').query
e = Entry.objects.filter(blog__in=q)
このクエリセットは、以下の SQL と等価です:
SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
また、上のコードは以下のようにも書けます:
inner_q = Blog.objects.filter(name__contains='Cheddar').values('pk').query
entries = Entry.objects.filter(blog__in=inner_q)
Warning
query
属性は、まだ明確に仕様の定まっていない内部的な属性です。
現在は上記のように問題なく使えますが、将来のバージョンで API が変更され
るかもしれません。
This second form is a bit less readable and unnatural to write, since it
accesses the internal query
attribute and requires a ValuesQuerySet
.
If your code doesn’t require compatibility with Django 1.0, use the first
form, passing in a queryset directly.
If you pass in a ValuesQuerySet
or ValuesListQuerySet
(the result of
calling values()
or values_list()
on a queryset) as the value to an
__in
lookup, you need to ensure you are only extracting one field in the
result. For example, this will work (filtering on the blog names):
inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)
This example will raise an exception, since the inner query is trying to extract two field values, where only one is expected:
# Bad code! Will raise a TypeError.
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)
Performance considerations
Be cautious about using nested queries and understand your database server’s performance characteristics (if in doubt, benchmark!). Some database backends, most notably MySQL, don’t optimize nested queries very well. It is more efficient, in those cases, to extract a list of values and then pass that into the second query. That is, execute two queries instead of one:
values = Blog.objects.filter(
name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))
Note the list()
call around the Blog QuerySet
to force execution of
the first query. Without it, a nested query would be executed, because
クエリセットは遅延評価される.
より大きい値に一致します。
使い方の例を示します:
Entry.objects.filter(id__gt=4)
これは、以下の SQL と等価です:
SELECT ... WHERE id > 4;
等しいか、より大きい値に一致します。
より少ない値に一致します。
等しいか、より少ない値に一致します。
大小文字を区別する starts-with です。
使い方の例を示します:
Entry.objects.filter(headline__startswith='Will')
これは、以下の SQL と等価です:
SELECT ... WHERE headline LIKE 'Will%';
SQLite は大小文字を区別する LIKE
をサポートしないので、 startswith
は istartswith
と同じになります。
大小文字を区別しない starts-with です。
使い方の例を示します:
Entry.objects.filter(headline__istartswith='will')
これは、以下の SQL と等価です:
SELECT ... WHERE headline ILIKE 'Will%';
SQLite users
When using the SQLite backend and Unicode (non-ASCII) strings, bear in mind the database note about string comparisons.
大小文字を区別する ends-with です。
使い方の例を示します:
Entry.objects.filter(headline__endswith='cats')
これは、以下の SQL と等価です:
SELECT ... WHERE headline LIKE '%cats';
SQLite users
SQLite は大小文字を区別する LIKE
をサポートしないので、 endswith
は iendswith
と同じです。Refer to the database note documentation for more.
大小文字を区別しない ends-with です。
使い方の例を示します:
Entry.objects.filter(headline__iendswith='will')
これは、以下の SQL と等価です:
SELECT ... WHERE headline ILIKE '%will'
SQLite users
When using the SQLite backend and Unicode (non-ASCII) strings, bear in mind the database note about string comparisons.
範囲テスト (閉包テスト) です。
使い方の例を示します:
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))
これは、以下の SQL と等価です:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
range
は日付、数値、文字など、SQL で BETWEEN
を使える場所ならどこで
も使えます。
date/datetime フィールドに対する、 year の厳密一致です。
使い方の例を示します:
Entry.objects.filter(pub_date__year=2005)
これは、以下の SQL と等価です:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31 23:59:59.999999';
(厳密な SQL シンタクスはデータベースエンジンによって違います。)
日付 (date) と日時 (datetime) フィールドに対する、 month の厳密一致です。 1 (1月) から 12 (12 月) までの整数を引数にとります。
使い方の例を示します:
Entry.objects.filter(pub_date__month=12)
これは、以下の SQL と等価です:
SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
(厳密な SQL シンタクスはデータベースエンジンによって違います。)
日付 (date) と日時 (datetime) フィールドに対する day の厳密一致です。
使い方の例を示します:
Entry.objects.filter(pub_date__day=3)
これは、以下の SQL と等価です:
SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
(厳密な SQL シンタクスはデータベースエンジンによって違います。)
このクエリ文は、「1 月 3 日」や「7 月 3 日」のように、毎月 3 日にマッチし ます。
For date and datetime fields, a ‘day of the week’ match.
Takes an integer value representing the day of week from 1 (Sunday) to 7 (Saturday).
Example:
Entry.objects.filter(pub_date__week_day=2)
(No equivalent SQL code fragment is included for this lookup because implementation of the relevant query varies among different database engines.)
Note this will match any record with a pub_date
that falls on a Monday (day
2 of the week), regardless of the month or year in which it occurs. Week days
are indexed with day 1 being Sunday and day 7 being Saturday.
Warning
When time zone support is enabled, Django
uses UTC in the database connection, which means the year
, month
,
day
and week_day
lookups are performed in UTC. This is a known
limitation of the current implementation.
True
または False
を引数にとり、それぞれが IS NULL
および
IS NOT NULL
に対応しています。
使い方の例を示します:
Entry.objects.filter(pub_date__isnull=True)
これは、以下の SQL と等価です:
SELECT ... WHERE pub_date IS NULL;
全文インデクスを活用した全文検索で、ブール値を返します。このメソッドは
contains
に似ていますが、全文インデクスを使うためはるかに高速です。
Example:
Entry.objects.filter(headline__search="+Django -jazz Python")
SQL equivalent:
SELECT ... WHERE MATCH(tablename, headline) AGAINST (+Django -jazz Python IN BOOLEAN MODE);
この機能は MySQL でだけ利用可能です。また、全文インデクスを追加するにはデー タベースを直接操作する必要があります。デフォルトの設定では、 Django は全文 検索に BOOLEAN MODE を使います。詳しくは MySQL のドキュメント を参照してください。
正規表現による大小文字を区別した検索を行います。
正規表現の構文は各データベースバックエンドで使われているものと同じです。
組み込みの正規表現サポートが無い sqlite
バックエンドの場合、
この機能は (Python で書かれた) ユーザ定義の REGEXP 関数で提供され、
したがって正規表現の文法は Python の re
モジュールと同じになります。
使い方の例を示します:
Entry.objects.get(title__regex=r'^(An?|The) +')
これは、以下の SQL と等価です:
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle
SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite
正規表現を指定する場合には raw 文字列を使う ('foo'
でなく r'foo'
を使う) よう勧めます。
正規表現による大小文字を区別しない検索を行います。
使い方の例を示します:
Entry.objects.get(title__iregex=r'^(an?|the) +')
これは、以下の SQL と等価です:
SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite
Django provides the following aggregation functions in the
django.db.models
module. For details on how to use these
aggregate functions, see
the topic guide on aggregation.
Avg
(field)¶Returns the mean value of the given field, which must be numeric.
<field>__avg
float
Count
(field, distinct=False)¶Returns the number of objects that are related through the provided field.
<field>__count
int
Has one optional argument:
distinct
¶If distinct=True
, the count will only include unique instances.
This is the SQL equivalent of COUNT(DISTINCT <field>)
. The default
value is False
.
Max
(field)¶Returns the maximum value of the given field.
<field>__max
Min
(field)¶Returns the minimum value of the given field.
<field>__min
StdDev
(field, sample=False)¶Returns the standard deviation of the data in the provided field.
<field>__stddev
float
Has one optional argument:
sample
¶By default, StdDev
returns the population standard deviation. However,
if sample=True
, the return value will be the sample standard deviation.
SQLite
SQLite doesn’t provide StdDev
out of the box. An implementation
is available as an extension module for SQLite. Consult the SQlite
documentation for instructions on obtaining and installing this
extension.
Sum
(field)¶Computes the sum of all values of the given field.
<field>__sum
Variance
(field, sample=False)¶Returns the variance of the data in the provided field.
<field>__variance
float
Has one optional argument:
sample
¶By default, Variance
returns the population variance. However,
if sample=True
, the return value will be the sample variance.
SQLite
SQLite doesn’t provide Variance
out of the box. An implementation
is available as an extension module for SQLite. Consult the SQlite
documentation for instructions on obtaining and installing this
extension.
Oct 26, 2017