QuerySet APIリファレンス—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/models/querysets
移動先:案内検索

QuerySet APIリファレンス

このドキュメントでは、QuerySet APIの詳細について説明します。 モデルおよびデータベースクエリガイドに記載されている資料に基づいているため、このドキュメントを読む前に、これらのドキュメントを読んで理解することをお勧めします。

このリファレンス全体を通して、データベースクエリガイドに示されているサンプルウェブログモデルを使用します。

QuerySetが評価されるとき

内部的には、QuerySetを構築、フィルタリング、スライスし、通常はデータベースに実際にアクセスすることなく渡すことができます。 クエリセットを評価するために何かを行うまで、データベースアクティビティは実際には発生しません。

QuerySetは次の方法で評価できます。

  • 反復。 QuerySetは反復可能であり、最初に反復したときにデータベースクエリを実行します。 たとえば、これにより、データベース内のすべてのエントリの見出しが出力されます。

    for e in Entry.objects.all():
        print(e.headline)

    注:少なくとも1つの結果が存在するかどうかを判断するだけの場合は、これを使用しないでください。 exits()を使用する方が効率的です。

  • スライス。 クエリセットの制限で説明されているように、QuerySetは、Pythonの配列スライス構文を使用してスライスできます。 未評価のQuerySetをスライスすると、通常、別の未評価のQuerySetが返されますが、スライス構文の「step」パラメーターを使用すると、Djangoはデータベースクエリを実行し、リストを返します。 評価されたQuerySetをスライスすると、リストも返されます。

    また、未評価のQuerySetをスライスすると、別の未評価のQuerySetが返されますが、それをさらに変更する(たとえば、フィルターを追加したり、順序を変更したりする)ことは許可されていません。これは、SQLに適切に変換されないためです。また、明確な意味もありません。

  • Pickling/Caching。QuerySets Picklingする場合の詳細については、次のセクションを参照してください。 このセクションの目的にとって重要なことは、結果がデータベースから読み取られることです。

  • repr()。 QuerySetは、repr()を呼び出すと評価されます。 これはPythonインタラクティブインタープリターの利便性のためであるため、APIをインタラクティブに使用するとすぐに結果を確認できます。

  • len()。 QuerySetは、len()を呼び出すと評価されます。 ご想像のとおり、これは結果リストの長さを返します。

    注:セット内のレコード数のみを決定する必要がある場合(実際のオブジェクトは必要ない場合)、SQLのSELECT COUNT(*)を使用してデータベースレベルでカウントを処理する方がはるかに効率的です。 Djangoは、まさにこの理由から count()メソッドを提供しています。

  • list()。 list()を呼び出して、QuerySetの評価を強制します。 例えば:

    entry_list = list(Entry.objects.all())
  • bool()。 bool()orandifステートメントは、クエリを実行させます。 結果が少なくとも1つある場合、QuerySetTrue、それ以外の場合はFalseです。 例えば:

    if Entry.objects.filter(headline="Test"):
       print("There is at least one Entry with the headline Test")

    注:少なくとも1つの結果が存在するかどうかだけを判断したい場合(実際のオブジェクトは必要ない場合)は、 exists()を使用する方が効率的です。

酸洗いQuerySet s

pickle a QuerySetの場合、これにより、ピクルス化する前にすべての結果が強制的にメモリにロードされます。 Picklingは通常、キャッシュの前兆として使用され、キャッシュされたクエリセットが再ロードされるときに、結果がすでに存在し、使用できる状態になっている必要があります(データベースからの読み取りには時間がかかり、キャッシュの目的が損なわれる可能性があります)。 つまり、QuerySetのピクルスを解除すると、現在データベースにある結果ではなく、ピクルス化された時点の結果が含まれます。

後でデータベースからQuerySetを再作成するために必要な情報のみを選択する場合は、QuerySetquery属性を選択します。 次に、次のようなコードを使用して、元のQuerySetを(結果をロードせずに)再作成できます。

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

query属性は不透明なオブジェクトです。 これはクエリ構築の内部を表し、パブリックAPIの一部ではありません。 ただし、ここで説明するように、属性の内容をピクルスおよびピクルス解除することは安全です(そして完全にサポートされています)。

QuerySet.values_list()の制限

ピクルス化されたquery属性を使用して QuerySet.values_list()を再作成すると、 QuerySet.values()に変換されます。

>>> import pickle
>>> qs = Blog.objects.values_list('id', 'name')
>>> qs
<QuerySet [(1, 'Beatles Blog')]>
>>> reloaded_qs = Blog.objects.all()
>>> reloaded_qs.query = pickle.loads(pickle.dumps(qs.query))
>>> reloaded_qs
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>

バージョン間で漬物を共有することはできません

QuerySetsのピクルスは、それらを生成するために使用されたバージョンのDjangoでのみ有効です。 DjangoバージョンNを使用してピクルスを生成する場合、ピクルスがDjangoバージョンN +1で読み取り可能であるという保証はありません。 ピクルスは、長期的なアーカイブ戦略の一部として使用するべきではありません。

サイレントに破損したオブジェクトなど、pickleの互換性エラーは診断が難しい場合があるため、pickle化されたバージョンとは異なるバージョンのDjangoでクエリセットをアンピックしようとすると、RuntimeWarningが発生します。


QuerySet API

QuerySetの正式な宣言は次のとおりです。

class QuerySet(model=None, query=None, using=None, hints=None)

通常、QuerySetを操作するときは、チェーンフィルターで使用します。 これを機能させるために、ほとんどのQuerySetメソッドは新しいクエリセットを返します。 これらの方法については、このセクションの後半で詳しく説明します。

QuerySetクラスには、イントロスペクションに使用できる2つのパブリック属性があります。

ordered

True QuerySetが注文された場合、つまり order_by()句またはモデルのデフォルトの順序があります。 それ以外の場合はFalse

db

このクエリが今実行された場合に使用されるデータベース。

ノート

QuerySetqueryパラメーターは、特殊なクエリサブクラスが内部クエリ状態を再構築できるようにするために存在します。 パラメータの値は、そのクエリ状態の不透明な表現であり、パブリックAPIの一部ではありません。

新しいQuerySetを返すメソッド

Djangoは、QuerySetによって返される結果のタイプ、またはSQLクエリの実行方法を変更する一連のQuerySetリファインメントメソッドを提供します。

filter()

filter(**kwargs)

指定されたルックアップパラメータに一致するオブジェクトを含む新しいQuerySetを返します。

ルックアップパラメータ(**kwargs)は、以下のフィールドルックアップで説明されている形式である必要があります。 複数のパラメーターは、基になるSQLステートメントのANDを介して結合されます。

より複雑なクエリ(たとえば、ORステートメントを使用したクエリ)を実行する必要がある場合は、 Qオブジェクトを使用できます。


exclude()

exclude(**kwargs)

指定されたルックアップパラメータと一致しないオブジェクトを含む新しいQuerySetを返します。

ルックアップパラメータ(**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以降であるか、見出しが「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'

2番目の例はより制限的であることに注意してください。

より複雑なクエリ(たとえば、ORステートメントを使用したクエリ)を実行する必要がある場合は、 Qオブジェクトを使用できます。


annotate()

annotate(*args, **kwargs)

QuerySet内の各オブジェクトに、提供されているクエリ式のリストで注釈を付けます。 式は、単純な値、モデル(または関連するモデル)のフィールドへの参照、または内のオブジェクトに関連するオブジェクトに対して計算された集計式(平均、合計など)の場合があります。 QuerySet

annotate()の各引数は、返されるQuerySetの各オブジェクトに追加される注釈です。

Djangoが提供する集計関数については、以下の集計関数で説明しています。

キーワード引数を使用して指定された注釈は、注釈のエイリアスとしてキーワードを使用します。 匿名引数には、集計関数の名前と集計されるモデルフィールドに基づいて生成されたエイリアスがあります。 匿名の引数にできるのは、単一のフィールドを参照する集計式のみです。 それ以外はすべてキーワード引数である必要があります。

たとえば、ブログのリストを操作している場合、各ブログに作成されたエントリの数を確認できます。

>>> from django.db.models import Count
>>> 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

集約の詳細については、集約に関するトピックガイドを参照してください。


alias()

alias(*args, **kwargs)

バージョン3.2の新機能。


annotate()と同じですが、QuerySetでオブジェクトに注釈を付ける代わりに、他のQuerySetメソッドで後で再利用できるように式を保存します。 これは、式自体の結果は必要ないが、フィルタリング、順序付け、または複雑な式の一部として使用される場合に役立ちます。 未使用の値を選択しないと、データベースから冗長な作業が削除され、パフォーマンスが向上します。

たとえば、エントリが5つを超えるブログを検索したいが、エントリの正確な数には関心がない場合は、次のようにします。

>>> from django.db.models import Count
>>> blogs = Blog.objects.alias(entries=Count('entry')).filter(entries__gt=5)

alias()は、 annotate()exclude()filter()order_by()と組み合わせて使用できます。 ]、および update()。 他のメソッドでエイリアス式を使用するには(例: Aggregate())、アノテーションにプロモートする必要があります:

Blog.objects.alias(entries=Count('entry')).annotate(
    entries=F('entries'),
).aggregate(Sum('entries'))

filter()order_by()は式を直接受け取ることができますが、式の作成と使用は同じ場所で行われないことがよくあります(たとえば、QuerySetメソッドは式を作成します) 、後でビューで使用するため)。 alias()を使用すると、複雑な式を段階的に作成でき、場合によっては複数のメソッドやモジュールにまたがり、エイリアスで式の部分を参照し、 annotate()のみを使用して最終結果を得ることができます。


order_by()

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('?')クエリは、使用しているデータベースバックエンドによっては、コストがかかり、時間がかかる場合があります。

別のモデルのフィールドで並べ替えるには、モデルリレーション間でクエリを実行する場合と同じ構文を使用します。 つまり、フィールドの名前、二重下線(__)、新しいモデルのフィールドの名前というように、参加するモデルの数が続きます。 例えば:

Entry.objects.order_by('blog__name', 'headline')

別のモデルとの関係であるフィールドで並べ替えようとすると、Djangoは関連モデルのデフォルトの順序を使用するか、 Meta.ordering が指定されていない場合は関連モデルの主キーで並べ替えます。 たとえば、Blogモデルにはデフォルトの順序が指定されていないため、次のようになります。

Entry.objects.order_by('blog')

…と同じです:

Entry.objects.order_by('blog__id')

Blogordering = ['name']がある場合、最初のクエリセットは次のようになります。

Entry.objects.order_by('blog__name')

式で asc()または desc()を呼び出すことにより、クエリ式で並べ替えることもできます。

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

asc()および desc()には、null値の並べ替え方法を制御する引数(nulls_firstおよびnulls_last)があります。

distinct()も使用している場合は、関連するモデルのフィールドで並べ替えるときに注意してください。 関連するモデルの順序によって期待される結果がどのように変化するかについては、 distinct()の注を参照してください。

ノート

複数値フィールドを指定して、結果を並べ替えることができます(たとえば、 ManyToManyField フィールド、または ForeignKey フィールドの逆の関係)。

この場合を考えてみましょう:

class Event(Model):
   parent = models.ForeignKey(
       'self',
       on_delete=models.CASCADE,
       related_name='children',
   )
   date = models.DateField()

Event.objects.order_by('children__date')

ここでは、Eventごとに複数の注文データが存在する可能性があります。 複数のchildrenを持つ各Eventは、order_by()が作成する新しいQuerySetに複数回返されます。 つまり、QuerySetorder_by()を使用すると、最初に作業していたよりも多くのアイテムが返される可能性があります。これは、おそらく予期されておらず、有用でもありません。

したがって、複数値フィールドを使用して結果を並べ替える場合は注意が必要です。 ' 注文するアイテムごとに、注文するデータが1つだけであると確信できる場合、このアプローチで問題が発生することはありません。 そうでない場合は、結果が期待どおりであることを確認してください。


順序で大文字と小文字を区別するかどうかを指定する方法はありません。 大文字と小文字の区別に関しては、Djangoが結果を並べ替えますが、データベースのバックエンドは通常結果を並べ替えます。

Lower を使用して小文字に変換されたフィールドで順序付けできます。これにより、大文字と小文字が一貫した順序付けが実現されます。

Entry.objects.order_by(Lower('headline').desc())

デフォルトの順序でさえも、クエリに順序を適用したくない場合は、パラメーターを指定せずに order_by()を呼び出します。

QuerySet.ordered 属性をチェックすることで、クエリが順序付けられているかどうかを確認できます。QuerySetが何らかの方法で順序付けられている場合は、Trueになります。

order_by()を呼び出すたびに、以前の注文はすべてクリアされます。 たとえば、このクエリはheadlineではなくpub_dateで並べ替えられます。

Entry.objects.order_by('headline').order_by('pub_date')

警告

注文は無料の操作ではありません。 注文に追加する各フィールドには、データベースにコストがかかります。 追加する各外部キーには、デフォルトの順序もすべて暗黙的に含まれます。

クエリに順序が指定されていない場合、結果はデータベースから指定されていない順序で返されます。 特定の順序付けは、結果内の各オブジェクトを一意に識別する一連のフィールドで順序付けする場合にのみ保証されます。 たとえば、nameフィールドが一意でない場合、それによる順序付けでは、同じ名前のオブジェクトが常に同じ順序で表示されるとは限りません。


reverse()

reverse()

reverse()メソッドを使用して、クエリセットの要素が返される順序を逆にします。 reverse()をもう一度呼び出すと、順序が通常の方向に戻ります。

クエリセットの「最後の」5つのアイテムを取得するには、次のようにします。

my_queryset.reverse()[:5]

これは、Pythonのシーケンスの最後からスライスすることとはまったく同じではないことに注意してください。 上記の例では、最初に最後のアイテムが返され、次に最後から2番目のアイテムが返されます。 Pythonシーケンスがあり、seq[-5:]を見ると、最後から5番目の項目が最初に表示されます。 Djangoは、SQLで効率的に行うことができないため、そのアクセスモード(最後からスライス)をサポートしていません。

また、reverse()は通常、順序が定義されているQuerySetでのみ呼び出す必要があることに注意してください(たとえば、デフォルトの順序を定義するモデルに対してクエリを実行する場合、または order_by( ))。 特定のQuerySetに対してそのような順序が定義されていない場合、その上でreverse()を呼び出しても、実際の効果はありません(reverse()を呼び出す前は順序が未定義であり、その後も未定義のままになります) 。


distinct()

distinct(*fields)

SQLクエリでSELECT DISTINCTを使用する新しいQuerySetを返します。 これにより、クエリ結果から重複する行が削除されます。

デフォルトでは、QuerySetは重複する行を削除しません。 Blog.objects.all()などの単純なクエリでは結果行が重複する可能性がないため、実際には、これが問題になることはめったにありません。 ただし、クエリが複数のテーブルにまたがっている場合、QuerySetが評価されたときに重複する結果が得られる可能性があります。 そのときはdistinct()を使用します。

ノート

order_by()呼び出しで使用されるフィールドはすべて、SQL SELECT列に含まれます。 distinct()と組み合わせて使用すると、予期しない結果が生じる場合があります。 関連するモデルのフィールドで並べ替えると、それらのフィールドが選択した列に追加され、重複した行が区別されるように見える場合があります。 返される結果には余分な列が表示されないため(順序付けをサポートするためにのみ存在します)、不明瞭な結果が返されているように見える場合があります。

同様に、 values()クエリを使用して選択した列を制限する場合、 order_by()(またはデフォルトのモデル順序)で使用される列は引き続き関与し、一意性に影響を与える可能性があります結果の。

ここでの教訓は、distinct()を使用している場合は、関連するモデルによる注文に注意することです。 同様に、distinct()values()を一緒に使用する場合は、 values()呼び出しにないフィールドで並べ替えるときに注意してください。


PostgreSQLの場合のみ、DISTINCTを適用するフィールドの名前を指定するために、位置引数(*fields)を渡すことができます。 これは、SELECT DISTINCT ON SQLクエリに変換されます。 これが違いです。 通常のdistinct()呼び出しの場合、データベースは、どの行が異なるかを判別するときに、各行のフィールドを比較します。 指定されたフィールド名を使用したdistinct()呼び出しの場合、データベースは指定されたフィールド名のみを比較します。

ノート

フィールド名を指定する場合、はQuerySetorder_by()を指定する必要があり、order_by()のフィールドはdistinct()、同じ順序で。

たとえば、SELECT DISTINCT ON (a)は、列aの各値の最初の行を示します。 順序を指定しないと、任意の行が表示されます。


例(最初のもの以降はPostgreSQLでのみ機能します):

>>> 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')
[...]

ノート

order_by()は、定義されているデフォルトの関連モデルの順序を使用することに注意してください。 DISTINCT ON式がORDER BY句の先頭の式と一致することを確認するために、リレーション_idまたは参照フィールドで明示的に順序付けする必要がある場合があります。 たとえば、Blogモデルが orderingnameで定義した場合:

Entry.objects.order_by('blog').distinct('blog')

…クエリはblog__nameで順序付けられ、DISTINCT ON式と一致しないため、機能しません。 両方の式が一致することを確認するには、リレーション_idフィールド(この場合はblog_id)または参照フィールド(blog__pk)で明示的に順序付けする必要があります。


values()

values(*fields, **expressions)

反復可能として使用される場合、モデルインスタンスではなくディクショナリを返すQuerySetを返します。

これらの各ディクショナリはオブジェクトを表し、キーはモデルオブジェクトの属性名に対応しています。

この例では、values()のディクショナリを通常のモデルオブジェクトと比較します。

# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
<QuerySet [<Blog: Beatles Blog>]>

# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>

values()メソッドは、オプションの位置引数*fieldsを取ります。これは、SELECTを制限するフィールド名を指定します。 フィールドを指定すると、各ディクショナリには、指定したフィールドのフィールドキー/値のみが含まれます。 フィールドを指定しない場合、各ディクショナリには、データベーステーブルのすべてのフィールドのキーと値が含まれます。

例:

>>> Blog.objects.values()
<QuerySet [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]>
>>> Blog.objects.values('id', 'name')
<QuerySet [{'id': 1, 'name': 'Beatles Blog'}]>

values()メソッドは、オプションのキーワード引数**expressionsも受け取ります。これらは、 annotate()に渡されます。

>>> from django.db.models.functions import Lower
>>> Blog.objects.values(lower_name=Lower('name'))
<QuerySet [{'lower_name': 'beatles blog'}]>

組み込みおよびカスタムルックアップを注文に使用できます。 例えば:

>>> from django.db.models import CharField
>>> from django.db.models.functions import Lower
>>> CharField.register_lookup(Lower)
>>> Blog.objects.values('name__lower')
<QuerySet [{'name__lower': 'beatles blog'}]>

values()句内の集計は、同じvalues()句内の他の引数の前に適用されます。 別の値でグループ化する必要がある場合は、代わりに以前のvalues()句に追加してください。 例えば:

>>> from django.db.models import Count
>>> Blog.objects.values('entry__authors', entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 20}, {'entry__authors': 1, 'entries': 13}]>
>>> Blog.objects.values('entry__authors').annotate(entries=Count('entry'))
<QuerySet [{'entry__authors': 1, 'entries': 33}]>

言及する価値のあるいくつかの微妙な点:

  • ForeignKey であるfooというフィールドがある場合、デフォルトのvalues()呼び出しは、foo_idという名前の辞書キーを返します。実際の値を格納する非表示モデル属性の(foo属性は関連モデルを参照します)。 values()を呼び出してフィールド名を渡す場合、fooまたはfoo_idのいずれかを渡すことができ、同じものが返されます(辞書キーはフィールドと一致します)渡した名前)。

    例えば:

    >>> Entry.objects.values()
    <QuerySet [{'blog_id': 1, 'headline': 'First Entry', ...}, ...]>
    
    >>> Entry.objects.values('blog')
    <QuerySet [{'blog': 1}, ...]>
    
    >>> Entry.objects.values('blog_id')
    <QuerySet [{'blog_id': 1}, ...]>
  • values()distinct()と一緒に使用する場合は、順序が結果に影響する可能性があることに注意してください。 詳細については、 distinct()の注記を参照してください。

  • extra()呼び出しの後にvalues()句を使用する場合、 extra()select引数で定義されたフィールドは明示的に指定する必要がありますvalues()呼び出しに含まれています。 values()呼び出しの後に行われた extra()呼び出しでは、余分に選択されたフィールドは無視されます。

  • values()の後に only()および defer()を呼び出すことは意味がないため、TypeErrorが発生します。

  • 変換と集計を組み合わせるには、明示的に、または values()へのキーワード引数として、2つの annotate()呼び出しを使用する必要があります。 上記のように、変換が関連するフィールドタイプに登録されている場合、最初の annotate()は省略できます。したがって、次の例は同等です。

    >>> from django.db.models import CharField, Count
    >>> from django.db.models.functions import Lower
    >>> CharField.register_lookup(Lower)
    >>> Blog.objects.values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.values(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>
    >>> Blog.objects.annotate(
    ...     entry__authors__name__lower=Lower('entry__authors__name')
    ... ).values('entry__authors__name__lower').annotate(entries=Count('entry'))
    <QuerySet [{'entry__authors__name__lower': 'test author', 'entries': 33}]>

これは、使用可能な少数のフィールドの値のみが必要であり、モデルインスタンスオブジェクトの機能は必要ないことがわかっている場合に役立ちます。 使用する必要のあるフィールドのみを選択する方が効率的です。

最後に、filter()order_by()などを呼び出すことができることに注意してください。 values()呼び出しの後、これは、これら2つの呼び出しが同一であることを意味します。

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

Djangoを作成した人々は、SQLに影響を与えるすべてのメソッドを最初に配置し、次に(オプションで)出力に影響を与えるメソッド(values()など)を配置することを好みますが、実際には問題ではありません。 これはあなたの個人主義を本当に誇示するあなたのチャンスです。

OneToOneFieldForeignKey、およびManyToManyField属性を介して、逆の関係を持つ関連モデルのフィールドを参照することもできます。

>>> Blog.objects.values('name', 'entry__headline')
<QuerySet [{'name': 'My blog', 'entry__headline': 'An entry'},
     {'name': 'My blog', 'entry__headline': 'Another entry'}, ...]>

警告

ManyToManyField 属性と逆の関係には、複数の関連する行が含まれる可能性があるため、これらを含めて、結果セットのサイズに乗数効果が生じる可能性があります。 これは、values()クエリにそのようなフィールドを複数含める場合に特に顕著になります。この場合、可能なすべての組み合わせが返されます。


SQLiteのJSONFieldのブール値

JSON_EXTRACT SQL関数がSQLiteに実装されている方法により、values()TrueおよびFalse


values_list()

values_list(*fields, flat=False, named=False)

これはvalues()に似ていますが、辞書を返す代わりに、繰り返したときにタプルを返す点が異なります。 各タプルには、values_list()呼び出しに渡されたそれぞれのフィールドまたは式からの値が含まれているため、最初の項目は最初のフィールドなどになります。 例えば:

>>> Entry.objects.values_list('id', 'headline')
<QuerySet [(1, 'First entry'), ...]>
>>> from django.db.models.functions import Lower
>>> Entry.objects.values_list('id', Lower('headline'))
<QuerySet [(1, 'first entry'), ...]>

1つのフィールドのみを渡す場合は、flatパラメーターを渡すこともできます。 Trueの場合、これは、返される結果が1タプルではなく単一値であることを意味します。 例を使用すると、違いがより明確になります。

>>> Entry.objects.values_list('id').order_by('id')
<QuerySet[(1,), (2,), (3,), ...]>

>>> Entry.objects.values_list('id', flat=True).order_by('id')
<QuerySet [1, 2, 3, ...]>

複数のフィールドがある場合、flatを渡すとエラーになります。

named=Trueを渡すと、結果をnamedtuple()として取得できます。

>>> Entry.objects.values_list('id', 'headline', named=True)
<QuerySet [Row(id=1, headline='First entry'), ...]>

名前付きタプルを使用すると、結果をより読みやすくすることができますが、結果を名前付きタプルに変換するためのパフォーマンスがわずかに低下します。

values_list()に値を渡さない場合、モデル内のすべてのフィールドが宣言された順序で返されます。

一般的なニーズは、特定のモデルインスタンスの特定のフィールド値を取得することです。 これを実現するには、values_list()に続いてget()呼び出しを使用します。

>>> Entry.objects.values_list('headline', flat=True).get(pk=1)
'First entry'

values()values_list()はどちらも、特定のユースケースの最適化を目的としています。モデルインスタンスを作成するオーバーヘッドなしにデータのサブセットを取得します。 このメタファーは、「1行、1オブジェクト」の仮定が成り立たないため、多対多およびその他の多値関係(逆外部キーの1対多関係など)を処理するときに崩壊します。

たとえば、 ManyToManyField を介してクエリを実行するときの動作に注意してください。

>>> Author.objects.values_list('name', 'entry__headline')
<QuerySet [('Noam Chomsky', 'Impressions of Gaza'),
 ('George Orwell', 'Why Socialists Do Not Believe in Fun'),
 ('George Orwell', 'In Defence of English Cooking'),
 ('Don Quixote', None)]>

複数のエントリがある作成者は複数回表示され、エントリのない作成者にはエントリの見出しにNoneがあります。

同様に、逆外部キーを照会すると、作成者がいないエントリに対してNoneが表示されます。

>>> Entry.objects.values_list('authors')
<QuerySet [('Noam Chomsky',), ('George Orwell',), (None,)]>

SQLiteのJSONFieldのブール値

JSON_EXTRACT SQL関数がSQLiteに実装されている方法により、values_list()TrueおよびFalse


dates()

dates(field, kind, order='ASC')

QuerySetのコンテンツ内の特定の種類の利用可能なすべての日付を表すdatetime.dateオブジェクトのリストに評価されるQuerySetを返します。

fieldは、モデルのDateFieldの名前である必要があります。 kindは、"year""month""week"、または"day"のいずれかである必要があります。 結果リスト内の各datetime.dateオブジェクトは、指定されたtypeに「切り捨て」られます。

  • "year"は、フィールドのすべての個別の年値のリストを返します。
  • "month"は、フィールドのすべての個別の年/月値のリストを返します。
  • "week"は、フィールドのすべての個別の年/週値のリストを返します。 すべての日付は月曜日になります。
  • "day"は、フィールドのすべての個別の年/月/日の値のリストを返します。

order(デフォルトは'ASC')は、'ASC'または'DESC'のいずれかである必要があります。 これは、結果の順序付け方法を指定します。

例:

>>> Entry.objects.dates('pub_date', 'year')
[datetime.date(2005, 1, 1)]
>>> Entry.objects.dates('pub_date', 'month')
[datetime.date(2005, 2, 1), datetime.date(2005, 3, 1)]
>>> Entry.objects.dates('pub_date', 'week')
[datetime.date(2005, 2, 14), datetime.date(2005, 3, 14)]
>>> Entry.objects.dates('pub_date', 'day')
[datetime.date(2005, 2, 20), datetime.date(2005, 3, 20)]
>>> Entry.objects.dates('pub_date', 'day', order='DESC')
[datetime.date(2005, 3, 20), datetime.date(2005, 2, 20)]
>>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
[datetime.date(2005, 3, 20)]

datetimes()

datetimes(field_name, kind, order='ASC', tzinfo=None, is_dst=None)

QuerySetのコンテンツ内の特定の種類の利用可能なすべての日付を表すdatetime.datetimeオブジェクトのリストに評価されるQuerySetを返します。

field_nameは、モデルのDateTimeFieldの名前である必要があります。

kindは、"year""month""week""day""hour""minute"のいずれかである必要があります。 、または"second"。 結果リスト内の各datetime.datetimeオブジェクトは、指定されたtypeに「切り捨て」られます。

order(デフォルトは'ASC')は、'ASC'または'DESC'のいずれかである必要があります。 これは、結果の順序付け方法を指定します。

tzinfoは、切り捨ての前に日時が変換されるタイムゾーンを定義します。 実際、特定の日時には、使用中のタイムゾーンに応じて異なる表現があります。 このパラメーターは、datetime.tzinfoオブジェクトである必要があります。 Noneの場合、Djangoは現在のタイムゾーンを使用します。 :setting: `USE_TZ`Falseの場合は効果がありません。

is_dstは、pytzが夏時間の存在しないあいまいな日時を解釈する必要があるかどうかを示します。 デフォルト(is_dst=Noneの場合)では、pytzはそのような日時の例外を発生させます。

バージョン3.1の新機能: is_dstパラメーターが追加されました。


ノート

この関数は、データベースで直接タイムゾーン変換を実行します。 結果として、データベースはtzinfo.tzname(None)の値を解釈できる必要があります。 これは、次の要件に変換されます。

  • SQLite:要件はありません。 変換は、 pytz (Djangoのインストール時にインストールされます)を使用してPythonで実行されます。
  • PostgreSQL:要件なし(タイムゾーンを参照)。
  • Oracle:要件なし(タイムゾーンファイルの選択を参照)。
  • MySQL: mysql_tzinfo_to_sql を使用してタイムゾーンテーブルをロードします。


none()

none()

none()を呼び出すと、オブジェクトを返さないクエリセットが作成され、結果にアクセスするときにクエリが実行されません。 qs.none()クエリセットは、EmptyQuerySetのインスタンスです。

例:

>>> Entry.objects.none()
<QuerySet []>
>>> from django.db.models.query import EmptyQuerySet
>>> isinstance(Entry.objects.none(), EmptyQuerySet)
True

all()

all()

現在のQuerySet(またはQuerySetサブクラス)のコピーを返します。 これは、モデルマネージャーまたはQuerySetのいずれかを渡して、結果をさらにフィルタリングする場合に役立ちます。 いずれかのオブジェクトでall()を呼び出すと、確実にQuerySetを操作できるようになります。

QuerySet評価されると、通常、結果がキャッシュされます。 QuerySetが評価されてからデータベース内のデータが変更された可能性がある場合は、以前に評価されたQuerySetall()を呼び出すことにより、同じクエリの更新結果を取得できます。


union()

union(*other_qs, all=False)

SQLのUNION演算子を使用して、2つ以上のQuerySetの結果を結合します。 例えば:

>>> qs1.union(qs2, qs3)

UNION演算子は、デフォルトで個別の値のみを選択します。 重複する値を許可するには、all=True引数を使用します。

union()intersection()、およびdifference()は、引数が他のQuerySetであっても、最初のQuerySetのタイプのモデルインスタンスを返します。モデル。 SELECTリストがすべてのQuerySetで同じである限り、異なるモデルの受け渡しは機能します(少なくともタイプ、タイプが同じ順序である限り、名前は重要ではありません) 。 このような場合、結果のQuerySetに適用されるQuerySetメソッドの最初のQuerySetの列名を使用する必要があります。 例えば:

>>> qs1 = Author.objects.values_list('name')
>>> qs2 = Entry.objects.values_list('headline')
>>> qs1.union(qs2).order_by('name')

さらに、LIMITOFFSETCOUNT(*)ORDER BY、および指定列(つまり、 スライス、 count()exists()order_by()、および values() / values_list()[ X106X])は、結果のQuerySetで許可されます。 さらに、データベースは、結合されたクエリで許可される操作に制限を課します。 たとえば、ほとんどのデータベースでは、結合されたクエリでLIMITまたはOFFSETを許可していません。


intersection()

intersection(*other_qs)

SQLのINTERSECT演算子を使用して、2つ以上のQuerySetの共有要素を返します。 例えば:

>>> qs1.intersection(qs2, qs3)

いくつかの制限については、 union()を参照してください。


difference()

difference(*other_qs)

SQLのEXCEPT演算子を使用して、QuerySetに存在する要素のみを保持し、他のQuerySetには存在しないようにします。 例えば:

>>> qs1.difference(qs2, qs3)

いくつかの制限については、 union()を参照してください。


extra()

extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

Djangoクエリ構文だけでは、複雑なWHERE句を簡単に表現できない場合があります。 これらのエッジケースのために、Djangoはextra() QuerySet修飾子を提供します— QuerySetによって生成されたSQLに特定の句を挿入するためのフックです。

最後の手段としてこの方法を使用してください

これは、将来のある時点で非推奨にすることを目指している古いAPIです。 他のquerysetメソッドを使用してクエリを表現できない場合にのみ使用してください。 使用する必要がある場合は、 QuerySet.extraキーワードを使用してチケットをユースケースとともに提出してください(最初に既存のチケットのリストを確認してください)。 extra()の削除を可能にするQuerySetAPI。 このメソッドのバグの改善や修正は行っていません。

たとえば、extra()のこの使用法は次のとおりです。

>>> qs.extra(
...     select={'val': "select col from sometable where othercol = %s"},
...     select_params=(someparam,),
... )

と同等です:

>>> qs.annotate(val=RawSQL("select col from sometable where othercol = %s", (someparam,)))

RawSQL を使用する主な利点は、必要に応じてoutput_fieldを設定できることです。 主な欠点は、生のSQLでクエリセットのテーブルエイリアスを参照すると、Djangoがそのエイリアスを変更する可能性があることです(たとえば、クエリセットがさらに別のクエリでサブクエリとして使用される場合)。


警告

extra()を使用するときは、十分に注意する必要があります。 SQLインジェクション攻撃から保護するために、使用するたびに、paramsを使用してユーザーが制御できるパラメーターをエスケープする必要があります。

また、SQL文字列でプレースホルダーを引用符で囲まないでください。 この例は、%sを引用符で囲んでいるため、SQLインジェクションに対して脆弱です。

SELECT col FROM sometable WHERE othercol = '%s'  # unsafe!

Djangoの SQLインジェクション保護がどのように機能するかについて詳しく読むことができます。


定義上、これらの追加のルックアップは、(SQLコードを明示的に記述しているため)異なるデータベースエンジンに移植できず、DRYの原則に違反する可能性があるため、可能であれば回避する必要があります。

paramsselectwheretablesのいずれかを指定してください。 引数は必須ではありませんが、少なくとも1つは使用する必要があります。

  • select

    select引数を使用すると、SELECT句に追加のフィールドを配置できます。 これは、属性名をSQL句にマッピングして、その属性を計算するために使用する辞書である必要があります。

    例:

    Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})

    その結果、各Entryオブジェクトには、エントリのpub_dateがJanより大きいかどうかを表すブール値であるis_recentという追加の属性があります。 1, 2006.

    Djangoは指定されたSQLスニペットをSELECTステートメントに直接挿入するため、上記の例の結果のSQLは次のようになります。

    SELECT blog_entry.*, (pub_date > '2006-01-01') AS is_recent
    FROM blog_entry;

    次の例はより高度です。 サブクエリを実行して、結果の各Blogオブジェクトにentry_count属性、関連するEntryオブジェクトの整数カウントを与えます。

    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) AS entry_count
    FROM blog_blog;

    サブクエリの周りのほとんどのデータベースエンジンで必要な括弧は、Djangoのselect句では必要ないことに注意してください。 また、一部のMySQLバージョンなど、一部のデータベースバックエンドはサブクエリをサポートしていないことに注意してください。

    まれに、extra(select=...)のSQLフラグメントにパラメーターを渡したい場合があります。 この目的のために、select_paramsパラメーターを使用します。

    これは、たとえば次のように機能します。

    Blog.objects.extra(
        select={'a': '%s', 'b': '%s'},
        select_params=('one', 'two'),
    )

    選択文字列内でリテラル%sを使用する必要がある場合は、シーケンス%%sを使用してください。

  • where / tables

    whereを使用して、明示的なSQL WHERE句を定義できます(おそらく非明示的な結合を実行するため)。 tablesを使用して、SQL FROM句にテーブルを手動で追加できます。

    wheretablesは両方とも文字列のリストを取ります。 すべてのwhereパラメータは、他の検索条件に「AND」されます。

    例:

    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])

    …(大まかに)次のSQLに変換されます。

    SELECT * FROM blog_entry WHERE (foo='a' OR bar='a') AND (baz='a')

    クエリですでに使用されているテーブルを指定する場合は、tablesパラメータを使用するときに注意してください。 tablesパラメーターを使用してテーブルを追加すると、Djangoは、テーブルが既に含まれている場合は、そのテーブルに余分な時間を含める必要があると想定します。 テーブル名にエイリアスが与えられるため、問題が発生します。 SQLステートメントにテーブルが複数回出現する場合、データベースがそれらを区別できるように、2回目以降のオカレンスではエイリアスを使用する必要があります。 追加のwhereパラメータで追加した追加のテーブルを参照している場合、これによりエラーが発生します。

    通常、クエリにまだ表示されていないテーブルのみを追加します。 ただし、上記のケースが発生した場合は、いくつかの解決策があります。 まず、余分なテーブルを含めずに処理できるかどうかを確認し、クエリにすでに含まれているテーブルを使用します。 それが不可能な場合は、クエリセット構造の先頭にextra()呼び出しを配置して、テーブルがそのテーブルの最初の使用になるようにします。 最後に、他のすべてが失敗した場合は、生成されたクエリを確認し、whereの追加を書き直して、追加のテーブルに指定されたエイリアスを使用します。 エイリアスは、同じ方法でクエリセットを作成するたびに同じになるため、エイリアス名が変更されないようにすることができます。

  • order_by

    extra()を介して含めた新しいフィールドまたはテーブルの一部を使用して結果のクエリセットを並べ替える必要がある場合は、order_byパラメータをextra()に使用し、一連の文字列を渡します。 これらの文字列は、table_name.column_name形式のモデルフィールド(クエリセットの通常の order_by()メソッドのように)または [で指定した列のエイリアスである必要があります。 X181X]パラメータをextra()に変更します。

    例えば:

    q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
    q = q.extra(order_by = ['-is_recent'])

    これにより、is_recentがtrueであるすべてのアイテムが結果セットの先頭に並べ替えられます(Trueは、Falseの前に降順で並べ替えられます)。

    ちなみに、これは、extra()を複数回呼び出すことができ、期待どおりに動作することを示しています(毎回新しい制約を追加します)。

  • params

    上記のwhereパラメーターは、標準のPythonデータベース文字列プレースホルダー— '%s'を使用して、データベースエンジンが自動的に引用するパラメーターを示す場合があります。 params引数は、置換される追加のパラメーターのリストです。

    例:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

    paramsは、特定のバックエンドに応じて値が正しく引用されるようにするため、値をwhereに直接埋め込むのではなく、常にparamsを使用してください。 たとえば、引用符は正しくエスケープされます。

    悪い:

    Entry.objects.extra(where=["headline='Lennon'"])

    良い:

    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

警告

MySQLでクエリを実行している場合、MySQLのサイレント型強制は、型を混合するときに予期しない結果を引き起こす可能性があることに注意してください。 文字列型の列でクエリを実行するが、整数値を使用する場合、MySQLは、比較を実行する前に、テーブル内のすべての値の型を整数に強制します。 たとえば、テーブルに値'abc''def'が含まれていて、WHERE mycolumn=0をクエリすると、両方の行が一致します。 これを防ぐには、クエリで値を使用する前に、正しい型キャストを実行してください。


defer()

defer(*fields)

複雑なデータモデリングの状況では、モデルに多くのフィールドが含まれている場合があり、その一部には多くのデータ(テキストフィールドなど)が含まれている場合や、Pythonオブジェクトに変換するためにコストのかかる処理が必要な場合があります。 最初にデータをフェッチするときに特定のフィールドが必要かどうかわからない状況でクエリセットの結果を使用している場合は、データベースからそれらを取得しないようにDjangoに指示できます。

これは、ロードしないフィールドの名前をdefer()に渡すことによって行われます。

Entry.objects.defer("headline", "body")

据え置きフィールドを持つクエリセットは、引き続きモデルインスタンスを返します。 各遅延フィールドにアクセスすると、データベースから各遅延フィールドが取得されます(一度にすべての遅延フィールドではなく、一度に1つずつ)。

defer()に対して複数の呼び出しを行うことができます。 呼び出しごとに、遅延セットに新しいフィールドが追加されます。

# Defers both the body and headline fields.
Entry.objects.defer("body").filter(rating=5).defer("headline")

フィールドが遅延セットに追加される順序は重要ではありません。 すでに延期されているフィールド名でdefer()を呼び出すことは無害です(フィールドは引き続き延期されます)。

標準の二重下線表記を使用して関連フィールドを区切ることにより、関連モデルのフィールドのロードを延期できます(関連モデルが select_related()を介してロードされている場合)。

Blog.objects.select_related().defer("entry__headline", "entry__body")

遅延フィールドのセットをクリアする場合は、Noneをパラメーターとしてdefer()に渡します。

# Load all fields immediately.
my_queryset.defer(None)

モデル内の一部のフィールドは、要求しても延期されません。 主キーのロードを延期することはできません。 select_related()を使用して関連モデルを取得している場合は、プライマリモデルから関連モデルに接続するフィールドの読み込みを延期しないでください。延期するとエラーが発生します。

ノート

defer()メソッド(およびその従兄弟である only()、以下)は、高度なユースケース専用です。 これらは、クエリを綿密に分析し、必要な情報を正確に理解し、必要なフィールドを返すこととモデルのフィールドの完全なセットとの違いが重要であることを測定した場合の最適化を提供します。

高度なユースケースの状況にあると思われる場合でも、クエリセットの読み込み時に追加のフィールドが必要かどうかを判断できない場合にのみdefer()を使用してください。 データの特定のサブセットを頻繁にロードして使用する場合は、モデルを正規化し、ロードされていないデータを別のモデル(およびデータベーステーブル)に配置するのが最善の選択です。 何らかの理由で列が1つのテーブルにとどまる必要がある場合は、Meta.managed = False管理属性のドキュメントを参照)を使用して、通常必要なフィールドのみを含むモデルを作成します。それをロードして、defer()と呼ぶ可能性のある場所で使用します。 これにより、コードが読者にとってより明確になり、Pythonプロセスでのメモリ消費量がわずかに速くなり、少し少なくなります。

たとえば、これらのモデルは両方とも、同じ基になるデータベーステーブルを使用します。

class CommonlyUsedModel(models.Model):
    f1 = models.CharField(max_length=10)

    class Meta:
        managed = False
        db_table = 'app_largetable'

class ManagedModel(models.Model):
    f1 = models.CharField(max_length=10)
    f2 = models.CharField(max_length=10)

    class Meta:
        db_table = 'app_largetable'

# Two equivalent QuerySets:
CommonlyUsedModel.objects.all()
ManagedModel.objects.all().defer('f2')

アンマネージモデルで多くのフィールドを複製する必要がある場合は、共有フィールドを使用して抽象モデルを作成してから、アンマネージモデルとマネージモデルを抽象モデルから継承するのが最適な場合があります。


ノート

遅延フィールドを持つインスタンスに対して save()を呼び出すと、ロードされたフィールドのみが保存されます。 詳細については、 save()を参照してください。


only()

only(*fields)

only()メソッドは、 defer()とほぼ逆です。 モデルを取得するときに延期されるべきではないフィールドを使用して呼び出します。 ほとんどすべてのフィールドを延期する必要があるモデルがある場合、only()を使用して補完的なフィールドのセットを指定すると、コードが単純になる可能性があります。

フィールドnameage、およびbiographyを持つモデルがあるとします。 次の2つのクエリセットは、遅延フィールドに関しては同じです。

Person.objects.defer("age", "biography")
Person.objects.only("name")

only()を呼び出すたびに、を置き換えて、すぐにロードするフィールドのセットを置き換えます。 メソッドの名前はニーモニックです。のみこれらのフィールドはすぐにロードされます。 残りは延期されます。 したがって、only()を連続して呼び出すと、最後のフィールドのみが考慮されます。

# This will defer all fields except the headline.
Entry.objects.only("body", "rating").only("headline")

defer()は段階的に動作するため(遅延リストにフィールドを追加)、only()defer()への呼び出しを組み合わせることができ、論理的に動作します。

# 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")

defer()ドキュメントの注記にあるすべての注意は、only()にも適用されます。 慎重に、他のオプションを使い果たした後にのみ使用してください。

only()を使用し、 select_related()を使用して要求されたフィールドを省略することもエラーです。

ノート

遅延フィールドを持つインスタンスに対して save()を呼び出すと、ロードされたフィールドのみが保存されます。 詳細については、 save()を参照してください。


using()

using(alias)

この方法は、複数のデータベースを使用している場合に、QuerySetが評価されるデータベースを制御するためのものです。 このメソッドが取る唯一の引数は、:setting: `DATABASES` で定義されているデータベースのエイリアスです。

例えば:

# queries the database with the 'default' alias.
>>> Entry.objects.all()

# queries the database with the 'backup' alias
>>> Entry.objects.using('backup')

select_for_update()

select_for_update(nowait=False, skip_locked=False, of=(), no_key=False)

トランザクションが終了するまで行をロックするクエリセットを返し、サポートされているデータベースでSELECT ... FOR UPDATE SQLステートメントを生成します。

例えば:

from django.db import transaction

entries = Entry.objects.select_for_update().filter(author=request.user)
with transaction.atomic():
    for entry in entries:
        ...

クエリセットが評価されると(この場合はfor entry in entries)、一致したすべてのエントリはトランザクションブロックが終了するまでロックされます。つまり、他のトランザクションがそれらのロックを変更または取得することはできません。

通常、別のトランザクションが選択した行の1つですでにロックを取得している場合、クエリはロックが解除されるまでブロックされます。 これが希望する動作でない場合は、select_for_update(nowait=True)を呼び出します。 これにより、通話が非ブロッキングになります。 競合するロックがすでに別のトランザクションによって取得されている場合、クエリセットの評価時に DatabaseError が発生します。 代わりにselect_for_update(skip_locked=True)を使用して、ロックされた行を無視することもできます。 nowaitskip_lockedは相互に排他的であり、両方のオプションを有効にしてselect_for_update()を呼び出そうとすると、ValueErrorになります。

デフォルトでは、select_for_update()はクエリによって選択されたすべての行をロックします。 たとえば、クエリセットのモデルの行に加えて、 select_related()で指定された関連オブジェクトの行がロックされます。 これが望ましくない場合は、 select_related()と同じフィールド構文を使用して、select_for_update(of=(...))にロックする関連オブジェクトを指定します。 クエリセットのモデルを参照するには、値'self'を使用します。

select_for_update(of=(...))で親モデルをロックします

マルチテーブル継承を使用するときに親モデルをロックする場合は、of引数に親リンクフィールド(デフォルトでは<parent_model_name>_ptr)を指定する必要があります。 例えば:

Restaurant.objects.select_for_update(of=('self', 'place_ptr'))

PostgreSQLでのみ、より弱いロックを取得するためにno_key=Trueを渡すことができます。これにより、ロックが設定されている間、ロックされた行を(外部キーなどを介して)単に参照する行を作成できます。 PostgreSQLのドキュメントには、行レベルのロックモードに関する詳細があります。

null許容型の関係でselect_for_update()を使用することはできません。

>>> Person.objects.select_related('hometown').select_for_update()
Traceback (most recent call last):
...
django.db.utils.NotSupportedError: FOR UPDATE cannot be applied to the nullable side of an outer join

この制限を回避するために、nullオブジェクトを気にしない場合は、それらを除外できます。

>>> Person.objects.select_related('hometown').select_for_update().exclude(hometown=None)
<QuerySet [<Person: ...)>, ...]>

現在、postgresqloracle、およびmysqlデータベースバックエンドは、select_for_update()をサポートしています。 ただし、MariaDB 10.3+はnowait引数のみをサポートし、MySQL8.0.1 +はnowaitskip_locked、およびof引数をサポートします。 no_key引数は、PostgreSQLでのみサポートされています。

MySQLなどのこれらのオプションをサポートしないデータベースバックエンドを使用して、nowait=Trueskip_locked=Trueno_key=True、またはofselect_for_update()に渡す NotSupportedError を発生させます。 これにより、コードが予期せずブロックされるのを防ぎます。

SELECT ... FOR UPDATEをサポートするバックエンドで自動コミットモードでselect_for_update()を使用してクエリセットを評価すると、行がロックされないため、 TransactionManagementError エラーになります。 許可されている場合、これはデータの破損を促進し、1つの外部のトランザクションで実行されることを期待するコードを呼び出すことによって簡単に引き起こされる可能性があります。

SELECT ... FOR UPDATEをサポートしないバックエンド(SQLiteなど)でselect_for_update()を使用しても効果はありません。 SELECT ... FOR UPDATEはクエリに追加されず、select_for_update()が自動コミットモードで使用されている場合でもエラーは発生しません。

警告

select_for_update()は通常、自動コミットモードで失敗しますが、 TestCase はトランザクション内の各テストを自動的にラップするため、の外部でもTestCaseselect_for_update()を呼び出します。 atomic()ブロックは、TransactionManagementErrorを発生させずに(おそらく予期せずに)通過します。 select_for_update()を適切にテストするには、 TransactionTestCase を使用する必要があります。


特定の式がサポートされていない場合があります

PostgreSQLは、 Window 式を使用したselect_for_update()をサポートしていません。


バージョン3.2で変更: no_key引数が追加されました。

of引数は、MySQL8.0.1以降で許可されていました。


raw()

raw(raw_query, params=(), translations=None)

生のSQLクエリを取得して実行し、django.db.models.query.RawQuerySetインスタンスを返します。 このRawQuerySetインスタンスは、通常のQuerySetと同じように繰り返して、オブジェクトインスタンスを提供できます。

詳細については、生のSQLクエリの実行を参照してください。

警告

raw()は常に新しいクエリをトリガーし、以前のフィルタリングを考慮しません。 そのため、通常はManagerまたは新しいQuerySetインスタンスから呼び出す必要があります。


バージョン3.2で変更: params引数のデフォルト値がNoneから空のタプルに変更されました。


新しいQuerySetを返す演算子

結合されたクエリセットは同じモデルを使用する必要があります。

AND(&)

SQL AND演算子を使用して、2つのQuerySetを結合します。

以下は同等です。

Model.objects.filter(x=1) & Model.objects.filter(y=2)
Model.objects.filter(x=1, y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) & Q(y=2))

同等のSQL:

SELECT ... WHERE x=1 AND y=2

または(|)

SQL OR演算子を使用して、2つのQuerySetを結合します。

以下は同等です。

Model.objects.filter(x=1) | Model.objects.filter(y=2)
from django.db.models import Q
Model.objects.filter(Q(x=1) | Q(y=2))

同等のSQL:

SELECT ... WHERE x=1 OR y=2

QuerySetを返さないメソッド

次のQuerySetメソッドは、QuerySetを評価し、以外の QuerySetを返します。

これらのメソッドはキャッシュを使用しません(キャッシュとクエリセットを参照)。 むしろ、呼び出されるたびにデータベースにクエリを実行します。

get()

get(**kwargs)

指定されたルックアップパラメータに一致するオブジェクトを返します。これは、フィールドルックアップで説明されている形式である必要があります。 一意性制約の主キーやフィールドなど、一意性が保証されているルックアップを使用する必要があります。 例えば:

Entry.objects.get(id=1)
Entry.objects.get(blog=blog, entry_number=1)

クエリセットがすでに1つの行を返すことが予想される場合は、引数なしでget()を使用して、その行のオブジェクトを返すことができます。

Entry.objects.filter(pk=1).get()

get()がオブジェクトを見つけられない場合、 Model.DoesNotExist 例外が発生します。

Entry.objects.get(id=-999) # raises Entry.DoesNotExist

get()が複数のオブジェクトを検出すると、 Model.MultipleObjectsReturned 例外が発生します。

Entry.objects.get(name='A Duplicated Name') # raises Entry.MultipleObjectsReturned

これらの例外クラスは両方ともモデルクラスの属性であり、そのモデルに固有です。 異なるモデルに対する複数のget()呼び出しからのこのような例外を処理する場合は、それらの汎用基本クラスを使用できます。 たとえば、 django.core.exceptions.ObjectDoesNotExist を使用して、複数のモデルからの DoesNotExist 例外を処理できます。

from django.core.exceptions import ObjectDoesNotExist

try:
    blog = Blog.objects.get(id=1)
    entry = Entry.objects.get(blog=blog, entry_number=1)
except ObjectDoesNotExist:
    print("Either the blog or entry doesn't exist.")

create()

create(**kwargs)

オブジェクトを作成してすべてを1つのステップで保存するための便利なメソッド。 したがって:

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()

get_or_create(defaults=None, **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()

ここで、同時リクエストを使用すると、同じパラメータでPersonを保存する試みが複数回行われる可能性があります。 この競合状態を回避するために、上記の例は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を返します。

警告

このメソッドは、データベースがキーワード引数の一意性を強制することを前提としたアトミックです( unique または unique_together を参照)。 キーワード引数で使用されるフィールドに一意性の制約がない場合、このメソッドを同時に呼び出すと、同じパラメーターを持つ複数の行が挿入される可能性があります。


get_or_create()filter()とチェーンし、 Qオブジェクトを使用することにより、取得したオブジェクトに対してより複雑な条件を指定できます。 たとえば、RobertまたはBob Marleyのいずれかが存在する場合はそれを取得し、存在しない場合は後者を作成します。

from django.db.models import Q

obj, created = Person.objects.filter(
    Q(first_name='Bob') | Q(first_name='Robert'),
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})

複数のオブジェクトが見つかった場合、get_or_create()MultipleObjectsReturned を発生させます。 オブジェクトが見つからない場合、get_or_create()は新しいオブジェクトをインスタンス化して保存し、新しいオブジェクトのタプルとTrueを返します。 新しいオブジェクトは、おおまかに次のアルゴリズムに従って作成されます。

params = {k: v for k, v in kwargs.items() if '__' not in k}
params.update({k: v() if callable(v) else v for k, v in defaults.items()})
obj = self.model(**params)
obj.save()

英語では、これは、二重アンダースコア(正確でないルックアップを示す)を含まない'defaults'以外のキーワード引数で開始することを意味します。 次に、defaultsの内容を追加し、必要に応じてすべてのキーをオーバーライドし、その結果をモデルクラスのキーワード引数として使用します。 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()を使用する方法について説明します。 正当な理由がない限り、POSTリクエストでのみ使用してください。 GETリクエストはデータに影響を与えないはずです。 代わりに、ページへのリクエストがデータに副作用をもたらす場合は常にPOSTを使用してください。 詳細については、HTTP仕様の 安全なメソッドを参照してください。

警告

get_or_create()から ManyToManyField 属性、および逆の関係を使用できます。 その場合、そのリレーションのコンテキスト内でクエリを制限します。 一貫して使用しないと、整合性の問題が発生する可能性があります。

次のモデルであること:

class Chapter(models.Model):
    title = models.CharField(max_length=255, unique=True)

class Book(models.Model):
    title = models.CharField(max_length=256)
    chapters = models.ManyToManyField(Chapter)

get_or_create()は、ブックのチャプターフィールドから使用できますが、フェッチはそのブックのコンテキスト内でのみ行われます。

>>> book = Book.objects.create(title="Ulysses")
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, True)
>>> book.chapters.get_or_create(title="Telemachus")
(<Chapter: Telemachus>, False)
>>> Chapter.objects.create(title="Chapter 1")
<Chapter: Chapter 1>
>>> book.chapters.get_or_create(title="Chapter 1")
# Raises IntegrityError

これは、本「ユリシーズ」を通じて「チャプター1」を取得または作成しようとしているために発生していますが、それらのいずれも実行できません。リレーションは、その本に関連していないため、そのチャプターをフェッチできませんが、 titleフィールドは一意である必要があるため、作成することもできません。


update_or_create()

update_or_create(defaults=None, **kwargs)

指定されたkwargsでオブジェクトを更新し、必要に応じて新しいオブジェクトを作成するための便利なメソッド。 defaultsは、オブジェクトの更新に使用される(フィールド、値)ペアのディクショナリです。 defaultsの値は呼び出し可能にすることができます。

(object, created)のタプルを返します。ここで、objectは作成または更新されたオブジェクトであり、createdは新しいオブジェクトが作成されたかどうかを指定するブール値です。

update_or_createメソッドは、指定されたkwargsに基づいてデータベースからオブジェクトをフェッチしようとします。 一致するものが見つかると、defaultsディクショナリに渡されたフィールドが更新されます。

これは、ボイラープラティッシュコードへのショートカットとして意図されています。 例えば:

defaults = {'first_name': 'Bob'}
try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
    for key, value in defaults.items():
        setattr(obj, key, value)
    obj.save()
except Person.DoesNotExist:
    new_values = {'first_name': 'John', 'last_name': 'Lennon'}
    new_values.update(defaults)
    obj = Person(**new_values)
    obj.save()

モデル内のフィールドの数が増えると、このパターンは非常に扱いにくくなります。 上記の例は、update_or_create()を使用して次のように書き直すことができます。

obj, created = Person.objects.update_or_create(
    first_name='John', last_name='Lennon',
    defaults={'first_name': 'Bob'},
)

kwargsで渡された名前の解決方法の詳細については、 get_or_create()を参照してください。

上記の get_or_create()で説明したように、このメソッドは競合状態になりやすく、データベースレベルで一意性が強制されていない場合、複数の行が同時に挿入される可能性があります。

get_or_create()create()のように、手動で指定した主キーを使用していて、オブジェクトを作成する必要があるが、キーがデータベースにすでに存在する場合は、 IntegrityError が発生します。


bulk_create()

bulk_create(objs, batch_size=None, ignore_conflicts=False)

このメソッドは、提供されたオブジェクトのリストを効率的な方法でデータベースに挿入し(通常、オブジェクトの数に関係なく1つのクエリのみ)、作成されたオブジェクトを提供されたのと同じ順序でリストとして返します。

>>> objs = Entry.objects.bulk_create([
...     Entry(headline='This is a test'),
...     Entry(headline='This is only a test'),
... ])

ただし、これにはいくつかの注意点があります。

  • モデルのsave()メソッドは呼び出されず、pre_saveおよびpost_save信号は送信されません。

  • マルチテーブル継承シナリオの子モデルでは機能しません。

  • モデルの主キーが AutoField の場合、主キー属性は特定のデータベース(現在はPostgreSQLおよびMariaDB 10.5+)でのみ取得できます。 他のデータベースでは設定されません。

  • 多対多の関係では機能しません。

  • objsをリストにキャストし、ジェネレーターの場合はobjsを完全に評価します。 キャストを使用すると、すべてのオブジェクトを検査できるため、手動で設定された主キーを持つオブジェクトを最初に挿入できます。 ジェネレータ全体を一度に評価せずにオブジェクトをバッチで挿入する場合は、オブジェクトに手動で設定された主キーがない限り、この手法を使用できます。

    from itertools import islice
    
    batch_size = 100
    objs = (Entry(headline='Test %s' % i) for i in range(1000))
    while True:
        batch = list(islice(objs, batch_size))
        if not batch:
            break
        Entry.objects.bulk_create(batch, batch_size)

batch_sizeパラメーターは、1回のクエリで作成されるオブジェクトの数を制御します。 デフォルトでは、クエリごとに最大999個の変数が使用されるデフォルトのSQLiteを除いて、すべてのオブジェクトを1つのバッチで作成します。

これをサポートするデータベース(Oracleを除くすべて)で、ignore_conflictsパラメーターをTrueに設定すると、データベースは、一意の値の重複など、制約に失敗する行の挿入の失敗を無視するようになります。 このパラメーターを有効にすると、各モデルインスタンスでの主キーの設定が無効になります(データベースが通常それをサポートしている場合)。

警告

MySQLとMariaDBでは、ignore_conflictsパラメーターをTrueに設定すると、重複キー以外の特定のタイプのエラーが警告に変わります。 厳密モードでも。 例:無効な値またはnull許容でない違反。 詳細については、 MySQLドキュメントおよび MariaDBドキュメントを参照してください。


バージョン3.1で変更: MariaDB10.5以降での主キー属性のフェッチのサポートが追加されました。


bulk_update()

bulk_update(objs, fields, batch_size=None)

このメソッドは、通常1つのクエリで、提供されたモデルインスタンスの指定されたフィールドを効率的に更新します。

>>> objs = [
...    Entry.objects.create(headline='Entry 1'),
...    Entry.objects.create(headline='Entry 2'),
... ]
>>> objs[0].headline = 'This is entry 1'
>>> objs[1].headline = 'This is entry 2'
>>> Entry.objects.bulk_update(objs, ['headline'])

QuerySet.update()は変更を保存するために使用されるため、モデルのリストを反復処理して各モデルでsave()を呼び出すよりも効率的ですが、いくつかの注意点があります。

  • モデルの主キーを更新することはできません。
  • 各モデルのsave()メソッドは呼び出されず、 pre_save および post_save シグナルは送信されません。
  • 多数の行の多数の列を更新する場合、生成されるSQLは非常に大きくなる可能性があります。 適切なbatch_sizeを指定して、これを回避してください。
  • マルチテーブル継承の祖先で定義されたフィールドを更新すると、祖先ごとに追加のクエリが発生します。
  • 個々のバッチに重複が含まれている場合、そのバッチの最初のインスタンスのみが更新されます。

batch_sizeパラメーターは、1回のクエリで保存されるオブジェクトの数を制御します。 デフォルトでは、クエリで使用される変数の数に制限があるSQLiteとOracleを除いて、すべてのオブジェクトを1つのバッチで更新します。


count()

count()

QuerySetに一致するデータベース内のオブジェクトの数を表す整数を返します。

例:

# Returns the total number of entries in the database.
Entry.objects.count()

# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()

count()呼び出しは、バックグラウンドでSELECT COUNT(*)を実行するため、すべてのレコードをPythonオブジェクトにロードしてlen()を呼び出すのではなく、常にcount()を使用する必要があります。結果(とにかくオブジェクトをメモリにロードする必要がある場合を除きます。その場合、len()の方が高速になります)。

QuerySet内のアイテムの数が必要であり、モデルインスタンスも取得している場合(たとえば、繰り返し処理することにより)、len(queryset)を使用する方がおそらく効率的であることに注意してください。 count()のように追加のデータベースクエリを発生させます。

クエリセットがすでに完全に取得されている場合、count()は、追加のデータベースクエリを実行するのではなく、その長さを使用します。


in_bulk()

in_bulk(id_list=None, *, field_name='pk')

フィールド値(id_list)とそれらの値のfield_nameのリストを取得し、各値を指定されたフィールド値を持つオブジェクトのインスタンスにマッピングする辞書を返します。 django.core.exceptions.ObjectDoesNotExist 例外がin_bulkによって発生することはありません。 つまり、どのインスタンスとも一致しないid_list値は単に無視されます。 id_listが指定されていない場合、クエリセット内のすべてのオブジェクトが返されます。 field_nameは、一意のフィールドまたは個別のフィールドである必要があります( distinct()で指定されたフィールドが1つしかない場合)。 field_nameのデフォルトは主キーです。

例:

>>> 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([])
{}
>>> Blog.objects.in_bulk()
{1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>, 3: <Blog: Django Weblog>}
>>> Blog.objects.in_bulk(['beatles_blog'], field_name='slug')
{'beatles_blog': <Blog: Beatles Blog>}
>>> Blog.objects.distinct('name').in_bulk(field_name='name')
{'Beatles Blog': <Blog: Beatles Blog>, 'Cheddar Talk': <Blog: Cheddar Talk>, 'Django Weblog': <Blog: Django Weblog>}

in_bulk()に空のリストを渡すと、空の辞書が作成されます。

バージョン3.2で変更:個別のフィールドの使用が許可されました。


iterator()

iterator(chunk_size=2000)

QuerySetを(クエリを実行して)評価し、結果に対してイテレータ( PEP 234 を参照)を返します。 QuerySetは通常、結果を内部にキャッシュするため、評価を繰り返しても追加のクエリが発生することはありません。 対照的に、iterator()は、QuerySetレベルでキャッシュを実行せずに、結果を直接読み取ります(内部的に、デフォルトのイテレーターはiterator()を呼び出し、戻り値をキャッシュします)。 一度だけアクセスする必要がある多数のオブジェクトを返すQuerySetの場合、これによりパフォーマンスが向上し、メモリが大幅に削減される可能性があります。

すでに評価されているQuerySetiterator()を使用すると、クエリが繰り返されて再度評価されることに注意してください。

また、iterator()を使用すると、以前のprefetch_related()呼び出しが無視されます。これは、これら2つの最適化が一緒に意味をなさないためです。

データベースのバックエンドに応じて、クエリ結果は一度に読み込まれるか、サーバー側のカーソルを使用してデータベースからストリーミングされます。

サーバー側カーソル付き

Oracleと PostgreSQL は、サーバー側カーソルを使用して、結果セット全体をメモリにロードせずに、データベースから結果をストリーミングします。

Oracleデータベースドライバは常にサーバー側カーソルを使用します。

サーバー側カーソルの場合、chunk_sizeパラメーターは、データベースドライバーレベルでキャッシュする結果の数を指定します。 より大きなチャンクをフェッチすると、メモリを犠牲にして、データベースドライバとデータベース間のラウンドトリップの数が減少します。

PostgreSQLでは、サーバー側カーソルは次の場合にのみ使用されます。 :setting: `DISABLE_SERVER_SIDE_CURSORS ` 設定はFalse 。 トランザクションプーリングモードで構成された接続プールを使用している場合は、トランザクションプーリングとサーバー側カーソルをお読みください。 サーバー側カーソルが無効になっている場合、動作はサーバー側カーソルをサポートしていないデータベースと同じです。


サーバー側カーソルなし

MySQLはストリーミング結果をサポートしていないため、Pythonデータベースドライバーは結果セット全体をメモリにロードします。 結果セットは、 PEP 249 で定義されているfetchmany()メソッドを使用して、データベースアダプターによってPython行オブジェクトに変換されます。

SQLiteはfetchmany()を使用して結果をバッチでフェッチできますが、SQLiteは接続内のクエリ間の分離を提供しないため、繰り返されるテーブルに書き込むときは注意してください。 詳細については、 QuerySet.iterator()を使用する場合の分離を参照してください。

chunk_sizeパラメーターは、Djangoがデータベースドライバーから取得するバッチのサイズを制御します。 バッチが大きくなると、メモリ消費量がわずかに増加しますが、データベースドライバとの通信のオーバーヘッドが減少します。

chunk_sizeのデフォルト値である2000は、 psycopgメーリングリストの計算に基づいています。

テキストデータと数値データが混在する10〜20列の行を想定すると、2000は100KB未満のデータをフェッチします。これは、ループが早期に終了した場合に転送される行数と破棄されるデータの間の適切な妥協点のようです。


latest()

latest(*fields)

指定されたフィールドに基づいて、テーブル内の最新のオブジェクトを返します。

この例では、pub_dateフィールドに従って、テーブル内の最新のEntryを返します。

Entry.objects.latest('pub_date')

いくつかのフィールドに基づいて最新のものを選択することもできます。 たとえば、2つのエントリのpub_dateが同じである場合に、Entryが最も早いexpire_dateで選択するには、次のようにします。

Entry.objects.latest('pub_date', '-expire_date')

'-expire_date'の負の符号は、expire_date降順の順序でソートすることを意味します。 latest()が最後の結果を取得するため、expire_dateが最も早いEntryが選択されます。

モデルの Metaget_latest_by が指定されている場合は、earliest()またはlatest()の引数を省略できます。 get_latest_by で指定されたフィールドがデフォルトで使用されます。

get()と同様に、earliest()およびlatest()は、指定されたパラメーターを持つオブジェクトがない場合、 DoesNotExist を発生させます。

earliest()latest()は、単に利便性と読みやすさのために存在することに注意してください。

earliest()およびlatest()は、日付がnullのインスタンスを返す場合があります。

順序付けはデータベースに委任されるため、異なるデータベースを使用すると、null値を許可するフィールドの結果の順序が異なる場合があります。 たとえば、PostgreSQLとMySQLはnull値をnull以外の値よりも大きいかのように並べ替えますが、SQLiteはその逆を行います。

null値を除外することをお勧めします。

Entry.objects.filter(pub_date__isnull=False).latest('pub_date')

earliest()

earliest(*fields)

それ以外の点では、方向が変更されることを除いて、 latest()と同様に機能します。


first()

first()

クエリセットに一致する最初のオブジェクトを返します。一致するオブジェクトがない場合はNoneを返します。 QuerySetに順序が定義されていない場合、クエリセットは主キーによって自動的に順序付けられます。 これは、 order_by()との相互作用で説明されているように集計結果に影響を与える可能性があります。

例:

p = Article.objects.order_by('title', 'pub_date').first()

first()は便利な方法であることに注意してください。次のコードサンプルは、上記の例と同等です。

try:
    p = Article.objects.order_by('title', 'pub_date')[0]
except IndexError:
    p = None

last()

last()

first()と同様に機能しますが、クエリセットの最後のオブジェクトを返します。


aggregate()

aggregate(*args, **kwargs)

QuerySetで計算された集計値(平均、合計など)のディクショナリを返します。 aggregate()の各引数は、返されるディクショナリに含まれる値を指定します。

Djangoが提供する集計関数については、以下の集計関数で説明しています。 集計はクエリ式でもあるため、集計を他の集計または値と組み合わせて、複雑な集計を作成できます。

キーワード引数を使用して指定された集計では、注釈の名前としてキーワードが使用されます。 匿名引数には、集計関数の名前と集計されるモデルフィールドに基づいて生成された名前が付けられます。 複雑な集計では匿名引数を使用できず、エイリアスとしてキーワード引数を指定する必要があります。

たとえば、ブログエントリを操作しているときに、ブログエントリを投稿した作成者の数を知りたい場合があります。

>>> from django.db.models import Count
>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}

キーワード引数を使用して集計関数を指定することにより、返される集計値の名前を制御できます。

>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}

集約の詳細については、集約に関するトピックガイドを参照してください。


exists()

exists()

QuerySet に結果が含まれている場合は、Trueを返し、含まれていない場合はFalseを返します。 これは、可能な限り最も単純で最速の方法でクエリを実行しようとしますが、通常の QuerySet クエリとほぼ同じクエリを実行します

exists()は、 QuerySet のオブジェクトメンバーシップと、 QuerySet のオブジェクトの存在の両方に関連する検索、特に大規模な QuerySet

一意のフィールドを持つモデルかどうかを見つける最も効率的な方法(例: primary_key)は QuerySet のメンバーです。

entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
    print("Entry contained in queryset")

これは、クエリセット全体を評価して反復する必要がある次のものよりも高速になります。

if entry in some_queryset:
   print("Entry contained in QuerySet")

また、クエリセットにアイテムが含まれているかどうかを確認するには、次のようにします。

if some_queryset.exists():
    print("There is at least one object in some_queryset")

どちらよりも高速になります:

if some_queryset:
    print("There is at least one object in some_queryset")

…しかし、それほどではありません(したがって、効率を上げるには大きなクエリセットが必要です)。

さらに、some_querysetがまだ評価されていないが、ある時点で評価されることがわかっている場合は、some_queryset.exists()を使用すると、より全体的な作業が行われます(存在チェックの1つのクエリと追加のクエリ) bool(some_queryset)は結果を取得し、返されたものがあるかどうかを確認します。


update()

update(**kwargs)

指定されたフィールドに対してSQL更新クエリを実行し、一致した行の数を返します(一部の行にすでに新しい値がある場合、更新された行の数と等しくない場合があります)。

たとえば、2010年に公開されたすべてのブログエントリのコメントをオフにするには、次のようにします。

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)

(これは、Entryモデルにフィールドpub_dateおよびcomments_onがあることを前提としています。)

複数のフィールドを更新できます—数に制限はありません。 たとえば、ここではcomments_onフィールドとheadlineフィールドを更新します。

>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old')

update()メソッドは即座に適用され、更新される QuerySet の唯一の制限は、関連するモデルではなく、モデルのメインテーブルの列のみを更新できることです。 たとえば、これを行うことはできません。

>>> Entry.objects.update(blog__name='foo') # Won't work!

ただし、関連するフィールドに基づくフィルタリングは引き続き可能です。

>>> Entry.objects.filter(blog__id=1).update(comments_on=True)

スライスが取得された QuerySetupdate()を呼び出すことはできません。

update()メソッドは、影響を受ける行の数を返します。

>>> 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

レコードを更新するだけで、モデルオブジェクトに対して何もする必要がない場合、最も効率的な方法は、モデルオブジェクトをメモリにロードするのではなく、update()を呼び出すことです。 たとえば、これを行う代わりに:

e = Entry.objects.get(id=10)
e.comments_on = False
e.save()

…これを行う:

Entry.objects.filter(id=10).update(comments_on=False)

update()を使用すると、オブジェクトのロードからsave()の呼び出しまでの短時間にデータベース内で何かが変更される可能性がある競合状態も防止されます。

最後に、update()はSQLレベルで更新を行うため、モデルでsave()メソッドを呼び出さず、 pre_save または[ X169X] post_save シグナル( Model.save()を呼び出した結果です)。 カスタム save()メソッドを持つモデルの一連のレコードを更新する場合は、それらをループして、次のように save()を呼び出します。

for e in Entry.objects.filter(pub_date__year=2010):
    e.comments_on = False
    e.save()
順序付けされたクエリセット

バージョン3.2の新機能。


order_by()update()のチェーンは、MariaDBとMySQLでのみサポートされており、異なるデータベースでは無視されます。 これは、競合することなく指定された順序で一意のフィールドを更新する場合に役立ちます。 例えば:

Entry.objects.order_by('-number').update(number=F('number') + 1)

ノート

order_by()句には、注釈、継承されたフィールド、またはリレーションにまたがるルックアップが含まれている場合は無視されます。


delete()

delete()

QuerySet のすべての行に対してSQL削除クエリを実行し、削除されたオブジェクトの数と、オブジェクトタイプごとの削除数を含むディクショナリを返します。

delete()は即座に適用されます。 スライスが取得された QuerySetdelete()を呼び出すことはできません。

たとえば、特定のブログのすべてのエントリを削除するには、次のようにします。

>>> b = Blog.objects.get(pk=1)

# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
(4, {'weblog.Entry': 2, 'weblog.Entry_authors': 2})

デフォルトでは、Djangoの ForeignKey はSQL制約ON DELETE CASCADEをエミュレートします。つまり、削除するオブジェクトを指す外部キーを持つオブジェクトも一緒に削除されます。 例えば:

>>> blogs = Blog.objects.all()

# This will delete all Blogs and all of their Entry objects.
>>> blogs.delete()
(5, {'weblog.Blog': 1, 'weblog.Entry': 2, 'weblog.Entry_authors': 2})

このカスケード動作は、 ForeignKey への on_delete 引数を介してカスタマイズできます。

delete()メソッドは一括削除を実行し、モデルでdelete()メソッドを呼び出しません。 ただし、削除されたすべてのオブジェクト(カスケード削除を含む)に対して pre_delete および post_delete シグナルを送信します。

Djangoは、シグナルを送信してカスケードを処理するために、オブジェクトをメモリにフェッチする必要があります。 ただし、カスケードとシグナルがない場合、Djangoは高速パスを使用して、メモリにフェッチせずにオブジェクトを削除する可能性があります。 大規模な削除の場合、これによりメモリ使用量が大幅に削減される可能性があります。 実行されるクエリの量も減らすことができます。

on_delete DO_NOTHINGに設定されているForeignKeysは、削除時に高速パスを使用することを妨げません。

オブジェクトの削除で生成されるクエリは、実装の詳細が変更される可能性があることに注意してください。


as_manager()

classmethod as_manager()

Manager のインスタンスとQuerySetのメソッドのコピーを返すクラスメソッド。 詳細については、 QuerySetメソッドを使用したマネージャーの作成を参照してください。


explain()

explain(format=None, **options)

QuerySetの実行プランの文字列を返します。この文字列には、使用されるインデックスや結合など、データベースがクエリを実行する方法が詳しく説明されています。 これらの詳細を知っていると、遅いクエリのパフォーマンスを向上させるのに役立つ場合があります。

たとえば、PostgreSQLを使用する場合:

>>> print(Blog.objects.filter(title='My Blog').explain())
Seq Scan on blog  (cost=0.00..35.50 rows=10 width=12)
  Filter: (title = 'My Blog'::bpchar)

出力はデータベース間で大幅に異なります。

explain()は、実装が簡単ではないため、Oracleを除くすべての組み込みデータベースバックエンドでサポートされています。

formatパラメーターは、出力形式をデータベースのデフォルト(通常はテキストベース)から変更します。 PostgreSQLは、'TEXT''JSON''YAML'、および'XML'形式をサポートしています。 MariaDBとMySQLは、'TEXT''TRADITIONAL'とも呼ばれます)および'JSON'形式をサポートしています。 MySQL 8.0.16+は、改良された'TREE'形式もサポートします。これは、PostgreSQLの'TEXT'出力に類似しており、サポートされている場合はデフォルトで使用されます。

一部のデータベースは、クエリに関する詳細情報を返すことができるフラグを受け入れます。 これらのフラグをキーワード引数として渡します。 たとえば、PostgreSQLを使用する場合:

>>> print(Blog.objects.filter(title='My Blog').explain(verbose=True, analyze=True))
Seq Scan on public.blog  (cost=0.00..35.50 rows=10 width=12) (actual time=0.004..0.004 rows=10 loops=1)
  Output: id, title
  Filter: (blog.title = 'My Blog'::bpchar)
Planning time: 0.064 ms
Execution time: 0.058 ms

一部のデータベースでは、フラグによってクエリが実行され、データベースに悪影響を与える可能性があります。 たとえば、MariaDB、MySQL 8.0.18+、およびPostgreSQLでサポートされているANALYZEフラグは、SELECTクエリの場合でも、トリガーがある場合、または関数が呼び出された場合にデータに変更をもたらす可能性があります。 。

バージョン3.1で変更: MySQL8.0.16以降での'TREE'形式のサポート、およびMariaDBとMySQL8.0.18以降でのanalyzeオプションのサポートが追加されました。


Fieldルックアップ

フィールドルックアップは、SQL WHERE句の要点を指定する方法です。 これらは、QuerySetメソッド filter()exclude()、および get()のキーワード引数として指定されます。

概要については、モデルとデータベースクエリのドキュメントを参照してください。

Djangoの組み込みルックアップを以下に示します。 モデルフィールドのカスタムルックアップを作成することもできます。

Entry.objects.get(id=14)のように)ルックアップタイプが提供されていない場合の便宜のために、ルックアップタイプは:lookup: `exact` であると想定されます。

exact

完全に一致。 比較のために提供された値がNoneの場合、SQL NULLとして解釈されます(詳細については、:lookup: `isnull` を参照してください)。

例:

Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)

同等のSQL:

SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;

MySQLの比較

MySQLでは、データベーステーブルの「照合」設定により、exactの比較で大文字と小文字が区別されるかどうかが決まります。 これはデータベース設定であり、ではなく Django設定です。 大文字と小文字を区別する比較を使用するようにMySQLテーブルを構成することは可能ですが、いくつかのトレードオフが関係します。 詳細については、データベースのドキュメントの照合セクションを参照してください。


iexact

大文字と小文字を区別しない完全一致。 比較のために提供された値がNoneの場合、SQL NULLとして解釈されます(詳細については、:lookup: `isnull` を参照してください)。

例:

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

同等のSQL:

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

最初のクエリは'Beatles Blog''beatles blog''BeAtLes BLoG'などに一致することに注意してください。

SQLiteユーザー

SQLiteバックエンドと非ASCII文字列を使用する場合は、文字列の比較に関するデータベースノートに注意してください。 SQLiteは、非ASCII文字列に対して大文字と小文字を区別しないマッチングを行いません。


contains

大文字と小文字を区別する封じ込めテスト。

例:

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

同等のSQL:

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

これは見出し'Lennon honored today'と一致しますが、'lennon honored today'とは一致しないことに注意してください。

SQLiteユーザー

SQLiteは、大文字と小文字を区別するLIKEステートメントをサポートしていません。 containsは、SQLiteのicontainsのように機能します。 詳細については、データベースノートを参照してください。


icontains

大文字と小文字を区別しない封じ込めテスト。

例:

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

同等のSQL:

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

SQLiteユーザー

SQLiteバックエンドと非ASCII文字列を使用する場合は、文字列の比較に関するデータベースノートに注意してください。


in

与えられた反復可能で; 多くの場合、リスト、タプル、またはクエリセット。 これは一般的なユースケースではありませんが、文字列(反復可能)は受け入れられます。

例:

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

同等のSQL:

SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');

リテラル値のリストを提供する代わりに、クエリセットを使用して値のリストを動的に評価することもできます。

inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)

このクエリセットは、subselectステートメントとして評価されます。

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

values()またはvalues_list()の結果であるQuerySet__inルックアップの値として渡す場合は、で1つのフィールドのみを抽出するようにする必要があります。結果。 たとえば、これは機能します(ブログ名のフィルタリング):

inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)

この例では、内部クエリが2つのフィールド値を抽出しようとしているため、例外が発生します。ここでは、1つだけが予期されています。

# 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)

パフォーマンスに関する考慮事項

ネストされたクエリの使用には注意し、データベースサーバーのパフォーマンス特性を理解してください(疑わしい場合はベンチマーク!)。 一部のデータベースバックエンド、特にMySQLは、ネストされたクエリを適切に最適化しません。 このような場合は、値のリストを抽出して、それを2番目のクエリに渡す方が効率的です。 つまり、1つではなく2つのクエリを実行します。

values = Blog.objects.filter(
        name__contains='Cheddar').values_list('pk', flat=True)
entries = Entry.objects.filter(blog__in=list(values))

最初のクエリの実行を強制するために、ブログQuerySetの周りのlist()呼び出しに注意してください。 これがないと、 QuerySetsがレイジーであるため、ネストされたクエリが実行されます。


gt

大なり記号。

例:

Entry.objects.filter(id__gt=4)

同等のSQL:

SELECT ... WHERE id > 4;

gte

以上。


lt

未満。


lte

以下。


startswith

大文字と小文字を区別します。

例:

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

同等のSQL:

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

SQLiteは、大文字と小文字を区別するLIKEステートメントをサポートしていません。 startswithは、SQLiteのistartswithのように機能します。


istartswith

大文字と小文字を区別しないで始まります。

例:

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

同等のSQL:

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

SQLiteユーザー

SQLiteバックエンドと非ASCII文字列を使用する場合は、文字列の比較に関するデータベースノートに注意してください。


endswith

大文字と小文字を区別します。

例:

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

同等のSQL:

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

SQLiteユーザー

SQLiteは、大文字と小文字を区別するLIKEステートメントをサポートしていません。 endswithは、SQLiteのiendswithのように機能します。 詳細については、データベースノートのドキュメントを参照してください。


iendswith

大文字と小文字を区別しないで終了します。

例:

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

同等のSQL:

SELECT ... WHERE headline ILIKE '%Lennon'

SQLiteユーザー

SQLiteバックエンドと非ASCII文字列を使用する場合は、文字列の比較に関するデータベースノートに注意してください。


range

範囲テスト(包括的)。

例:

import datetime
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を使用できる場所であればどこでも使用できます。日付、数字、さらには文字にも使用できます。

警告

DateTimeFieldを日付でフィルタリングすると、境界が「指定された日付の午前0時」として解釈されるため、最終日のアイテムは含まれません。 pub_dateDateTimeFieldの場合、上記の式は次のSQLに変換されます。

SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

一般的に、日付と日時を混在させることはできません。


date

日時フィールドの場合、値を日付としてキャストします。 追加のフィールドルックアップを連鎖させることができます。 日付値を取ります。

例:

Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

:setting: `USE_TZ`Trueの場合、フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


year

日付フィールドと日時フィールドの場合、正確な年が一致します。 追加のフィールドルックアップを連鎖させることができます。 整数年かかります。

例:

Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)

同等のSQL:

SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date >= '2005-01-01';

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


iso_year

日付フィールドと日時フィールドの場合、ISO8601の週番号と年が完全に一致します。 追加のフィールドルックアップを連鎖させることができます。 整数年かかります。

例:

Entry.objects.filter(pub_date__iso_year=2005)
Entry.objects.filter(pub_date__iso_year__gte=2005)

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


month

日付フィールドと日時フィールドの場合、月が完全に一致します。 追加のフィールドルックアップを連鎖させることができます。 1(1月)から12(12月)までの整数を取ります。

例:

Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)

同等のSQL:

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

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


day

日付フィールドと日時フィールドの場合、完全な曜日が一致します。 追加のフィールドルックアップを連鎖させることができます。 整数日かかります。

例:

Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)

同等のSQL:

SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';

(正確なSQL構文は、データベースエンジンごとに異なります。)

これは、1月3日、7月3日など、月の3日目のpub_dateを持つすべてのレコードと一致することに注意してください。

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


week

日付フィールドと日時フィールドの場合は、 ISO-8601 に従って週番号(1-52または53)を返します。つまり、週は月曜日に始まり、最初の週にはその年の最初の木曜日が含まれます。

例:

Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


week_day

日付フィールドと日時フィールドの場合、「曜日」が一致します。 追加のフィールドルックアップを連鎖させることができます。

1(日曜日)から7(土曜日)までの曜日を表す整数値を取ります。

例:

Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

これは、発生する月または年に関係なく、月曜日(週の2日目)に該当するpub_dateのすべてのレコードと一致することに注意してください。 平日は、1日目が日曜日、7日目が土曜日として索引付けされます。

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


iso_week_day

バージョン3.1の新機能。


日付フィールドと日時フィールドの場合、正確なISO8601曜日が一致します。 追加のフィールドルックアップを連鎖させることができます。

1(月曜日)から7(日曜日)までの曜日を表す整数値を取ります。

例:

Entry.objects.filter(pub_date__iso_week_day=1)
Entry.objects.filter(pub_date__iso_week_day__gte=1)

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

これは、発生する月または年に関係なく、月曜日(曜日)に該当するpub_dateのすべてのレコードと一致することに注意してください。 平日は、1日目が月曜日、7日目が日曜日でインデックス付けされます。

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


quarter

日付フィールドと日時フィールドの場合、「年の四半期」が一致します。 追加のフィールドルックアップを連鎖させることができます。 1年の四半期を表す1から4までの整数値を取ります。

第2四半期(4月1日から6月30日)のエントリを取得する例:

Entry.objects.filter(pub_date__quarter=2)

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


time

日時フィールドの場合、値を時間としてキャストします。 追加のフィールドルックアップを連鎖させることができます。 datetime.timeの値を取ります。

例:

Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))

(関連するクエリの実装はデータベースエンジンによって異なるため、このルックアップには同等のSQLコードフラグメントは含まれていません。)

:setting: `USE_TZ`Trueの場合、フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


hour

日時フィールドと時間フィールドの場合、正確な時間一致。 追加のフィールドルックアップを連鎖させることができます。 0から23までの整数を取ります。

例:

Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)

同等のSQL:

SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12';

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


minute

日時フィールドと時間フィールドの場合、完全に一致します。 追加のフィールドルックアップを連鎖させることができます。 0から59までの整数を取ります。

例:

Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)

同等のSQL:

SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29';

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


second

日時フィールドと時刻フィールドの場合、完全に2番目に一致します。 追加のフィールドルックアップを連鎖させることができます。 0から59までの整数を取ります。

例:

Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)

同等のSQL:

SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31';

(正確なSQL構文は、データベースエンジンごとに異なります。)

:setting: `USE_TZ`Trueの場合、日時フィールドはフィルタリングの前に現在のタイムゾーンに変換されます。 これには、データベースタイムゾーン定義が必要です。


isnull

TrueまたはFalseのいずれかを取ります。これらは、それぞれIS NULLおよびIS NOT NULLのSQLクエリに対応します。

例:

Entry.objects.filter(pub_date__isnull=True)

同等のSQL:

SELECT ... WHERE pub_date IS NULL;

バージョン3.1以降非推奨:右側に非ブール値を使用することは非推奨です。代わりにTrueまたはFalseを使用してください。 Django 4.0では、例外が発生します。


regex

大文字と小文字を区別する正規表現の一致。

正規表現の構文は、使用中のデータベースバックエンドの構文です。 正規表現のサポートが組み込まれていない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

正規表現構文を渡すには、生の文字列('foo'の代わりにr'foo'など)を使用することをお勧めします。


iregex

大文字と小文字を区別しない正規表現の一致。

例:

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は、django.db.modelsモジュールで次の集計関数を提供します。 これらの集計関数の使用方法の詳細については、集計に関するトピックガイドを参照してください。 アグリゲートの作成方法については、 Aggregate のドキュメントを参照してください。

警告

SQLiteは、箱から出して日付/時刻フィールドの集計を処理できません。 これは、SQLiteにネイティブの日付/時刻フィールドがなく、Djangoが現在テキストフィールドを使用してこれらの機能をエミュレートしているためです。 SQLiteの日付/時刻フィールドで集計を使用しようとすると、NotSupportedErrorが発生します。


ノート

集計関数は、空のQuerySetとともに使用すると、Noneを返します。 たとえば、QuerySetにエントリが含まれていない場合、Sum集計関数は0ではなくNoneを返します。 例外はCountで、QuerySetが空の場合は0を返します。


すべての集計には、次の共通のパラメーターがあります。

expressions

モデルのフィールド、フィールドの変換、またはクエリ式を参照する文字列。

バージョン3.2で変更:フィールドの変換のサポートが追加されました。


output_field

戻り値のモデルフィールドを表すオプションの引数

ノート

複数のフィールドタイプを組み合わせる場合、Djangoはすべてのフィールドが同じタイプである場合にのみoutput_fieldを判別できます。 それ以外の場合は、output_fieldを自分で用意する必要があります。


filter

集約される行をフィルタリングするために使用されるオプションの Qオブジェクト

使用例については、条件付き集計および注釈のフィルタリングを参照してください。


**extra

アグリゲートによって生成されたSQLに追加のコンテキストを提供できるキーワード引数。


Avg

class Avg(expression, output_field=None, distinct=False, filter=None, **extra)

指定された式の平均値を返します。別のoutput_fieldを指定しない限り、数値である必要があります。

  • デフォルトのエイリアス:<field>__avg

  • 戻りタイプ:入力がintの場合はfloat、それ以外の場合は入力フィールドと同じ、または指定されている場合はoutput_field

オプションの引数が1つあります。

distinct

distinct=Trueの場合、Avgは一意の値の平均値を返します。 これは、AVG(DISTINCT <field>)に相当するSQLです。 デフォルト値はFalseです。


Count

class Count(expression, distinct=False, filter=None, **extra)

指定された式を介して関連付けられているオブジェクトの数を返します。

  • デフォルトのエイリアス:<field>__count

  • 返品タイプ:int

オプションの引数が1つあります。

distinct

distinct=Trueの場合、カウントには一意のインスタンスのみが含まれます。 これは、COUNT(DISTINCT <field>)に相当するSQLです。 デフォルト値はFalseです。


Max

class Max(expression, output_field=None, filter=None, **extra)
指定された式の最大値を返します。
  • デフォルトのエイリアス:<field>__max
  • 戻りタイプ:入力フィールドと同じ、または指定されている場合はoutput_field


Min

class Min(expression, output_field=None, filter=None, **extra)
指定された式の最小値を返します。
  • デフォルトのエイリアス:<field>__min
  • 戻りタイプ:入力フィールドと同じ、または指定されている場合はoutput_field


StdDev

class StdDev(expression, output_field=None, sample=False, filter=None, **extra)

指定された式のデータの標準偏差を返します。

  • デフォルトのエイリアス:<field>__stddev

  • 戻りタイプ:入力がintの場合はfloat、それ以外の場合は入力フィールドと同じ、または指定されている場合はoutput_field

オプションの引数が1つあります。

sample

デフォルトでは、StdDevは母標準偏差を返します。 ただし、sample=Trueの場合、戻り値はサンプルの標準偏差になります。


Sum

class Sum(expression, output_field=None, distinct=False, filter=None, **extra)

指定された式のすべての値の合計を計算します。

  • デフォルトのエイリアス:<field>__sum

  • 戻りタイプ:入力フィールドと同じ、または指定されている場合はoutput_field

オプションの引数が1つあります。

distinct

distinct=Trueの場合、Sumは一意の値の合計を返します。 これは、SUM(DISTINCT <field>)に相当するSQLです。 デフォルト値はFalseです。


Variance

class Variance(expression, output_field=None, sample=False, filter=None, **extra)

指定された式のデータの分散を返します。

  • デフォルトのエイリアス:<field>__variance

  • 戻りタイプ:入力がintの場合はfloat、それ以外の場合は入力フィールドと同じ、または指定されている場合はoutput_field

オプションの引数が1つあります。

sample

デフォルトでは、Varianceは母分散を返します。 ただし、sample=Trueの場合、戻り値はサンプル分散になります。