このドキュメントの Django のバージョンにはセキュリティ上の脆弱性があるため、すでにサポートが終了されています。新しいバージョンにアップグレードしてください!最新の Django のバージョンのドキュメントはこちら

Django v1.0 documentation

QuerySet API リファレンス

revision-up-to:8961 (1.0)

このドキュメントでは、 クエリセット(QuerySet) API について詳しく解説し ます。このドキュメントは、 モデルデータベースクエリ に基づいて書かれているので、 あらかじめ読んでおくよう勧めます。

このリファレンスを通じて、例題には データベースクエリガイド で取り上げた ブログのモデル例 を使います。

クエリセットはいつ評価されるのか

内部的には、クエリセットの生成、フィルタ操作、スライス、コード間の受渡しは、 データベースを操作することなく行えます。クエリセットを何らかの形で評価しな い限り、データベースの操作は実際には起こらないのです。

以下の方法を使うと、クエリセットを評価できます:

  • イテレーション。 クエリセットはイテレーション可能オブジェクトであ り、オブジェクトに対して最初にイテレーション操作を行ったときにデータ ベースクエリを実行します。例えば、以下の例はデータベース中の全てのエ ントリのヘッドラインを出力します:

    for e in Entry.objects.all():
        print e.headline
    
  • スライス。 クエリセットに制約を課す で説明しているように、 Python の配列スライス表記を使うとクエリセットをスライスできます。通常、 クエリセットに対するスライスは (未評価の) 別のクエリセットを返します が、スライス表記に「ステップ (step)」パラメタを使った場合には、データ ベースクエリを実行します。

  • repr(). クエリセットに対して repr() を呼び出すと、クエリセッ トは値評価されます。これは Python 対話インタプリタでの利便性のための 仕様で、 API を対話的に使うときに結果を即座に見られるようにしています。

  • len(). クエリセットに対して len() を呼び出すと、クエリセッ トは値評価されます。予想に違わず、 len() はクエリ結果リストの長さ を返します。

    注意: クエリセット中のレコードの数を知りたいだけなら、 len()使わないでください 。レコード数の計算はデータベース上で SQL 文の SELECT COUNT(*) 使って行う方が遥かに効率的であり、まさにその理由 から Django では count() メソッドを提供しています。後述の count() を参照してください。

  • list(). クエリセットに対して list() を呼び出すと、値評価を強 制できます。例えば:

    entry_list = list(Entry.objects.all())
    

    とはいえ、この方法を使うと、Django が全ての要素のリストをメモリ上にロー ドするため、巨大なメモリオーバヘッドを引き起こす可能性があるので十分 注意してください。これに対し、クエリセットに対するイテレーション操作 では、必要な分だけデータをロードしてオブジェクトをインスタンス化する という利点があります。

クエリセット API

クエリセットは手動で作成できません (Manager を介してしか生成できま せん) が、 QuerysSet クラスのコンストラクタの正式な定義は以下の通りです:

class QuerySet([model=None])

通常、クエリセットを操作するときには、 フィルタを連鎖 させます。クエリセットに対するフィルタ操作は、ほとんど が新たなクエリセットを返します。

新たなクエリセットを返すクエリセットメソッド

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'

二つ目の例の方が制約が厳しいことに注意して下さい。

order_by(*fields)

デフォルトでは、 QuerySet の返す結果はモデルの Metaordering オプションに指定した整列条件のタプルに従って整列されます。 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() によってどのように影響を受けるかは、 distinct() の説明を参照してください。

クエリ結果の整列には、 (ManyToMany のような)複数の値で構成されるフィー ルドも指定できます。通常、こうした指定にはあまり意味がなく、本当に高度な使 い方です。しかし、クエリセットをフィルタした結果や、もともとのデータにおい て、リレーション元のオブジェクトから参照しているオブジェクトが一つしかない ことが暗黙的に決まっているとはっきりしていれば、整列結果は期待通りになるで しょう。複数の値で構成されるフィールドで整列を行う場合には、十分注意して、 期待通りの結果が得られるか確認してください。

Django 1.0 で新たに登場しました.

クエリをデフォルトの整列も含めて一切整列させたくない場合には、 order_by() を引数なしで呼び出してください。

Django 1.0 で新たに登場しました.

リレーションをまたいでモデルを整列する際の構文が変更されました。以前の動作 仕様は Django 0.96 のドキュメント を参照してください。

大小文字の区別を考慮して整列するかどうかを指定する方法はありません。大小文 字の区別については、 Django は現在使っているデータベースバックエンドの整列 方法に従います。

また、 reverse() は一般に、すでに整列方法の定義されているクエリセット (デフォルトの整列順の定義されたモデルから取り出したクエリセットや、 order_by() で整列されたもの) に対して呼びだすべきものです。整列方法の定 義されていないクエリセットに対して reverse() を呼び出しても、何ら効果 をもたらしません (reverse() を呼び出す前に整列方法が定義されていなけれ ば、呼び出した後の整列方法も未定義のままです)。

distinct()

SQL クエリに SELECT DISTINCT を使う新たな QuerySet を返します。 distinct() を使うと、クエリ結果から重複する行をなくします。

デフォルトでは、 QuerySet は重複する行を除去しません。通常は、 Blog.objects.all() のような単純なクエリは重複する行を含むような結果にな らないため、これはあまり問題ではありません。しかし、クエリが複数のテーブル にわたる場合、 QuerySet の評価結果に重複する結果が入る場合があります。 その場合には distinct() を使って下さい。

Note

order_by(*fields) に指定したフィールドは、 SQL レベルで SELECT されます。そのため、 order_by()distinct() と組み合わせると 予期しない結果を生むことがあります。例えば、リレーション先のモデルフィー ルドを使って整列を行うと、それらのフィールドも SELECT されるため、 リレーション元のオブジェクトは同じ値で、リレーション先のフィールド値だ けが違うレコードは異なる (distinct) レコードとみなされます。リレーショ ン先のレコードカラムは (順序を制御するために使われるだけなので) 返され ず、その結果、distinct 制約を満たしていないクエリ結果が返されるように見 えてしまいます。

同様に、 values() クエリを使って SELECT 対象のカラムを制約する 場合も、 order_by() に指定したカラム (またはモデルのデフォルトの順 序制御カラム) が自動的にクエリ結果に含められ、結果の一意性に影響を及ぼ します。

distinct() を使う場合、リレーション先のフィールドを使った並べ替えに はよく注意しましょう。同様に、 distinct()values() を同時に 使うときにも、 values() の対象とするフィールドに順序カラムが入って いない場合はよく注意してください。

values(*fields)

ValueQuerySet を返します。 ValueQuerySetQuerySet のサブクラ スで、評価結果としてモデルインスタンスオブジェクトの代りに辞書のリストを返 す 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'}]

注意すべき点が 2 つほどあります:

  • values() メソッドは ManyToManyField の 内容を返しません。 ManyToManyField 型のフィー ルド名を渡すと、エラーを送出します。

  • ForeignKey foo がモデルに入っている場 合、 values() がデフォルトで返す辞書には、 foo_id というキー が入ります。これは、リレーションの実際の値が入っているモデル内部の隠 しフィールドの名前です (foo はリレーション先のモデルインスタンス への参照です)。一方、 values() にフィールド名を指定して呼び出す 場合は、 foofoo_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() の節を参照してください。

Django 1.0 で新たに登場しました.

以前は、 values() に渡せるのは blog だけで、 blog_id は使えませ んでした。

ValuesQuerySet が便利なのは、わずかな数のフィールドの値しか必要でなく、 モデルインスタンスオブジェクトの機能が必要でないと分かっている場合です。 必要なフィールドだけを選択すると、さらに効率的です。

最後に、 ValuesQuerySetQuerySet のサブクラスなので、 QuerySet の全てのメソッドを持っている点に注意してください。 ValuesQuerySet に対して filter()order_by() といった操作を行 えます。つまり、以下の二つの呼び出しは等価です:

Blog.objects.values().order_by('id')
Blog.objects.order_by('id').values()

Django の作者たちは、全ての SQL 関係のメソッドを先に配置し、その後に (必要 なら) 出力関係のメソッド (values() など) を配置するやり方を好んでいます。 とはいえ、これは実際上問題ではないので、個人的な信条を反映させてかまいませ ん。

values_list(*fields)

Django 1.0 で新たに登場しました.

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 を返します。 DateQuerySetQuerySet のサブクラス で、評価結果としてクエリセット内のコンテンツの全日付を 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)]

none()

Django 1.0 で新たに登場しました.

EmptyQuerySet を返します。 EmptyQuerySet とは、評価結果が常に空の リストであるクエリセットです。関数の戻り値などで空の照合結果を返したいけれ ども、呼び出し側が (空のリストなどではなく) クエリセットオブジェクトの戻り 値を期待しているような場合に便利です。

例:

>>> Entry.objects.none()
[]

select_related()

自動的に外部キーのリレーションを「追跡」し、クエリを実行したときにリレーショ ン先のオブジェクトも加えて選択するような QuerySet を返します。 これはパフォーマンスを向上させるための機構で、クエリは (ときに非常に) 巨大 になりますが、以後の外部キーへのリレーションでデータベースクエリが必要なく なります。

以下の例では、通常の照合と select_related() を使った照合との違いを比較 しています。通常の照合では:

# データベースを操作します。
e = Entry.objects.get(id=5)

# リレーション先の Blog オブジェクトを取得するために再度データベースを
# 操作します。
b = e.blog

一方、 select_related() を使った照合では:

# データベースを操作します。
e = Entry.objects.select_related().get(id=5)

# e.blog は上のクエリで取得済みなので、データベースを操作しません。
b = e.blog

select_related は可能な限り外部キーを追跡することに注意してください。以 下のようなモデル:

class City(models.Model):
    # ...

class Person(models.Model):
    # ...
    hometown = models.ForeignKey(City)

class Book(models.Model):
    # ...
    author = models.ForeignKey(Person)

の場合、 Book.objects.select_related().get(id=4) を実行すると、リレーションの張られた Person に加えて City もキャッ シュします:

b = Book.objects.select_related().get(id=4)
p = b.author         # データベースを操作しません。
c = p.hometown       # データベースを操作しません。

b = Book.objects.get(id=4) # select_related() しない場合
p = b.author         # データベースを操作します。
c = p.hometown       # データベースを操作します。

select_related() は、デフォルトの状態では null=True であるような外 部キーカラムを追跡しないので注意してください。

通常、 select_related() を使うと、データベースの呼び出し回数を減らせる ので、大幅にパフォーマンスを向上できます。しかし、リレーションが深くネスト しているような状況では、 select_related() が追跡するリレーションが「多 すぎる」ために、巨大なクエリを生成してしまい、結果的にパフォーマンスの低下 を招く場合があります。

こうした状況に対応するため、 select_related()depth 引数を指定す ると、以下の例のようにリレーションを何「レベル」まで追跡するかを制御できま す:

b = Book.objects.select_related(depth=1).get(id=4)
p = b.author         # 追跡済みのリレーション。データベースを操作しません。
c = p.hometown       # 未追跡のリレーション。データベースを呼び出します。
Django 1.0 で新たに登場しました.

depth 引数は Django 1.0 で新たに追加された機能です。

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')
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 の一部のバージョンのように、データベースバックエンドに よってはサブクエリをサポートしないので注意してください。

Django 1.0 で新たに登場しました.

ごく稀に、 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 節に手動でテーブル名を追加できま す。

wheretables は、ともに文字列のリストを引数にとります。 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'])

QuerySet を返さないクエリセットメソッド

以下のクエリセットメソッドは、クエリセットを評価して、クエリセット でない 値を返します。

これらのメソッドはキャッシュを使わず (後述の キャッシュとクエリセット を参照してください)、メソッド呼び出しごとにデータベースにクエリをかけます。

get(**kwargs)

照合パラメタに一致するオブジェクトを返します。照合パラメタは後述の フィールドの照合 で説明するフォーマットにします。

複数のオブジェクトがみつかると、 get()AssertionError を送出しま す。

指定パラメタに対するオブジェクトが見つからなかった場合には get()DoesNotExist 例外を送出します。 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 仕様における 安全なメソッド を参照してください。

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 を評価し (クエリを実行し) て、その結果の入った イテレータ を返します。 QuerySet は通常、最初にアクセスした時点で、全ての検索結果 を読み込んで、対応するオブジェクトのインスタンスを生成してしまいます。 一方、 iterator() は、離散的なチャンク単位で検索結果を読み出し、オブジェ クトをインスタンス化して、一度に一つづつ yield します。 QuerySet は膨大 な数のオブジェクトを返す場合があるので、その場合には iterator() を使う ことでパフォーマンスを改善し、メモリの使用量を劇的に減らせます。

すでに値にアクセス済みの QuerySet に対して iterator() を呼び出すと、 値の評価が再度行われ、クエリが繰り返し発行されるので注意してください。

latest(field_name=None)

日付フィールドである field_name の値に応じて、テーブル中の最新のオブジェ クトを返します。

以下の例では、 pub_date フィールドに応じて、テーブル中の最新の Entry を返します:

Entry.objects.latest('pub_date')

モデルの Metaget_latest_by を指定している場合、 latest()field_name 引数は省略できます。 Django は get_latest_by に指定し たフィールドをデフォルト値にします。

get() と同様、 latest() は指定パラメタに一致するオブジェクトがない 場合に DoesNotExist を送出します。

latest() は純粋に利便性と可読性のためだけに存在しています。

フィールドの照合

フィールドの照合操作によって、 SQL の WHERE 節の中身が決まります。フィー ルドの照合を行うには、 filter(), exclude() および get() といっ たクエリセットのメソッドのキーワード引数を指定します。

フィールド照合について知りたければ、 フィールドの照合 を参照して ください。

exact

厳密な一致です、比較対象の値を 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;
Django 1.0 で変更されました: バージョン 1.0 から、 id__exact=None のセマンティクスが変更されまし た。以前は SQL レベルで (意図的に) WHERE id = NULL に置き換えられて いましたが、この SQL はいかなるレコードにもマッチしません。バージョン 1.0 では、 id__isnull=True と同じ挙動を示すように変更されています。

MySQL での比較

MySQL では、デフォルト構成での exact 比較の判定は大小文字を区別しま せん。大小文字の区別は、データベーステーブルごとのコレーション (collation) 設定で制御されています (データベースの設定であって、 Django の設定では ありません)。 MySQL のテーブルは大小文字を区別して比較する ように構成できますが、トレードオフもあります。詳しくは、 databases ドキュメントの コレーションの節 を参照してください。

iexact

大小文字の区別をしない一致です。

使い方の例を示します:

Blog.objects.get(name__iexact='beatles blog')

これは、以下の SQL と等価です:

SELECT ... WHERE name ILIKE 'beatles blog';

この例は、 'Beatles Blog', 'beatles blog', 'BeAtLes BLoG' などにマッチします。

contains

大小文字を区別する包含テストです。

使い方の例を示します:

Entry.objects.get(headline__contains='Lennon')

これは、以下の SQL と等価です:

SELECT ... WHERE headline LIKE '%Lennon%';

この例では、 'Today Lennon honored' というヘッドラインには一致しますが、 'today lennon honored' には一致しません。

SQLite は大小文字を区別する LIKE をサポートしないので、 containsicontains と同じになります。

icontains

大小文字を区別しない包含テストです。

使い方の例を示します:

Entry.objects.get(headline__icontains='Lennon')

これは、以下の SQL と等価です:

SELECT ... WHERE headline ILIKE '%Lennon%';

in

指定のリストに入っているものに一致します。

使い方の例を示します:

Entry.objects.filter(id__in=[1, 3, 4])

これは、以下の SQL と等価です:

SELECT ... WHERE id IN (1, 3, 4);

リテラル値のリストを渡す代わりに、クエリセットを使って動的なリストとして評 価してもかまいません。クエリセットは values() メソッドを使って個々のオ ブジェクト値からなるリストに変換できねばならず、 query 属性を使ってクエ リセットに変換してから渡さねばなりません:

q = Blog.objects.filter(name__contains='Cheddar').values('pk').query
e = Entry.objects.filter(blog__in=q)

Warning

query 属性は、まだ明確に仕様の定まっていない内部的な属性です。 現在は上記のように問題なく使えますが、将来のバージョンで API が変更され るかもしれません。

上のクエリセットを評価すると、以下の SQL 文と同様の結果を得ます:

SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')

gt

より大きい値に一致します。

使い方の例を示します:

Entry.objects.filter(id__gt=4)

これは、以下の SQL と等価です:

SELECT ... WHERE id > 4;

gte

等しいか、より大きい値に一致します。

lt

より少ない値に一致します。

lte

等しいか、より少ない値に一致します。

startswith

大小文字を区別する starts-with です。

使い方の例を示します:

Entry.objects.filter(headline__startswith='Will')

これは、以下の SQL と等価です:

SELECT ... WHERE headline LIKE 'Will%';

SQLite は大小文字を区別する LIKE をサポートしないので、 startswithistartswith と同じになります。

istartswith

大小文字を区別しない starts-with です。

使い方の例を示します:

Entry.objects.filter(headline__istartswith='will')

これは、以下の SQL と等価です:

SELECT ... WHERE headline ILIKE 'Will%';

endswith

大小文字を区別する ends-with です。

使い方の例を示します:

Entry.objects.filter(headline__endswith='cats')

これは、以下の SQL と等価です:

SELECT ... WHERE headline LIKE '%cats';

SQLite は大小文字を区別する LIKE をサポートしないので、 endswithiendswith と同じです。

iendswith

大小文字を区別しない ends-with です。

使い方の例を示します:

Entry.objects.filter(headline__iendswith='will')

これは、以下の SQL と等価です:

SELECT ... WHERE headline ILIKE '%will'

range

範囲テスト (閉包テスト) です。

使い方の例を示します:

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 を使える場所ならどこで も使えます。

year

date/datetime フィールドに対する、 year の厳密一致です。

使い方の例を示します:

Entry.objects.filter(pub_date__year=2005)

これは、以下の SQL と等価です:

SELECT ... WHERE EXTRACT('year' FROM pub_date) = '2005';

(厳密な SQL シンタクスはデータベースエンジンによって違います。)

month

date/datetime フィールドに対する、 month の厳密一致です。 1 (1月) から 12 (12 月) までの整数を引数にとります。

使い方の例を示します:

Entry.objects.filter(pub_date__month=12)

これは、以下の SQL と等価です:

SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';

(厳密な SQL シンタクスはデータベースエンジンによって違います。)

day

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 日にマッチし ます。

isnull

True または False を引数にとり、それぞれが IS NULL および IS NOT NULL に対応しています。

使い方の例を示します:

Entry.objects.filter(pub_date__isnull=True)

これは、以下の SQL と等価です:

SELECT ... WHERE pub_date IS NULL;

__isnull=True__exact=None

__isnull=True__exact=None には重要な違いがあります。 SQL の仕様上、いかなる値も NULL と等価ではないので、 __exact=None常に 空の結果セットを返します。一方、 __isnull はフィールドの値が NULL であるかどうかだけを調べ、比較 を実行しません。

regex

Django 1.0 で新たに登場しました.

正規表現による大小文字を区別した検索を行います。

正規表現の構文は各データベースバックエンドで使われているものと同じです。 正規表現による照合をサポートしない sqlite バックエンドの場合に、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' を 使う)よう勧めます。

iregex

Django 1.0 で新たに登場しました.

正規表現による大小文字を区別しない検索を行います。

使い方の例を示します:

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