データのフィルタリングとソート
次のメソッドを使用してデータをフィルタリングできます(sql where句)。
-
filter(*args, **kwargs) -> QuerySet -
exclude(*args, **kwargs) -> QuerySet -
get(*args,**kwargs)->モデル
-
get_or_none(*args, **kwargs) -> Optional[Model] -
get_or_create(_defaults: Optional[Dict[str, Any]] = None, *args, **kwargs) -> Tuple[Model, bool] -
all(*args, **kwargs) -> List[Optional[Model]] -
クエリセットエージェント
QuerysetProxy.filter(*args, **kwargs)方法QuerysetProxy.exclude(*args, **kwargs)方法QuerysetProxy.get(*args, **kwargs)方法QuerysetProxy.get_or_none(*args, **kwargs)方法QuerysetProxy.get_or_create(_defaults: Optional[Dict[str, Any]] = None, *args, **kwargs)方法QuerysetProxy.all(*args, **kwargs)方法
と、次のメソッドを使用してデータをソートします(sql order by句)。
order_by(columns:Union[List, str, OrderAction]) -> QuerySet- クエリセットエージェント
QuerysetProxy.order_by(columns:Union[List, str, OrderAction])方法
フィルタリング
フィルタリング
filter(*args, **kwargs) -> QuerySet
クロスFKリレーションシップのフィルターを使用して、任意のモデルプロパティ/フィールドでインスタンスをフィルタリングおよび取得できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Djangoスタイルのフィルター
特別なフィルタサフィックスを使用して、フィルタオペランドを変更できます。
- 精密-値と正確に一致し、sql列=
*はアルバム__name__正確='Malibu'と書くことができます。 - i正確-sql列=
を正確に一致させる(大文字と小文字を区別しない) - はアルバム__name__i正確='malibu'と書くことができます。
- が含まれています-sql列LIKE'%
%'*はアルバム__name__include='Mal'と書くことができます。 - icontains-sql列LIKE'%
%'(大文字と小文字を区別しない)*はアルバム__name__icontains='mal'と書くことができます。 - はsqlで
column IN (<VALUE1>, <VALUE2>, ...)*album__name__in=['Malibu', 'Barclay']と書くことができる - isnull SQL列IS NULL(およびSQL列IS NOT NULL)
- はalbum__name__isnull=True(isnotnull album__name_\isnull=False)と書くことができる
- gt-sql列>
(大きい)*position_\gt=3と書くことができる - gte-sql列>=
(以上)*position_\gte=3と書くことができる - lt-sql列<
(下)*position_=3と書くことができる - lte-sql列<=
(以下)*position_\lte=3と書くことができる - startswith-sql列LIKE'
%'(正確な開始マッチング)*アルバム__name__startswith='Mal'と書くことができます。 - istartswithsql列LIKE'
%'(大文字と小文字を区別しない)* album__name__istartswith='mal'と書くことができる - endswith-sql列LIKE'%
'(正確な終了マッチング)*アルバムと書くことができます__名前__endswith='ibu' - iendswith-sql列LIKE'%
'(大文字と小文字を区別しない)*アルバムと書くことができます__名前__iendswith='IBU'
いくつかのサンプル:
1 2 3 4 5 6 7 8 9 10 11 | |
Pythonスタイルのフィルター
- 正確-値と正確に一致し、SQL列=
- Malibuと書くことTrack.album.nameできます。
- i正確-正確に一致するsql列=
(大文字と小文字を区別しない) - 書くことができます
Track.album.name.iexact('malibu')
- 書くことができます
- には-sql列LIKE'%
%'*はTrack.album.name%'Mal')*は Track.album.name.contains('Mal')と書くことができる - icontens-sql列LIKE'%
%'(大文字と小文字を区別しない)* Track.album.name.icontains('mal')と書くことができる - はsqlで
column IN (<VALUE1>, <VALUE2>, ...)*はTrack.album.name << ['Malibu', 'Barclay']*はTrack.album.name.in_(['Malibu', 'Barclay'])と書くことができる - isnul-sql列IS NULL(およびsql列IS NOT NULL)*はTrack.album.nameと書くことができます>>None*はTrack.album.nameと書くことができます. isnull(True)*はと書くことができます
Not nullは
Track.album.name.isnull(False)*not nullとして書くことができます~(Track.album.name>>None)*not nullは~(Track.album.name.isnull(True))と書くことができます - gt-sql列>
(大きい)*はTrack.album.name>3と書くことができる - gte-sql列>=
(以上)*Track.album.name>=3と書くことができる - lt-sql列<
(下)*はTrack.album.name<3と書くことができる - lte-sql列<=
(以下等しい)*はTrack.album.name<=3と書くことができる - startswithsql列LIKE'
%'(正確な開始マッチング)* Track.album.name.startswith('Mal')と書くことができます - istartswithsql列LIKE'
%'(大文字と小文字を区別しない)* Track.album.name.istartswith('mal')と書くことができる - endswithsql列LIKE'%
'(正確な終了マッチング)* Track.album.name.endswith('ibu')と書くことができます - iendswithsql列LIKE'%
'(大文字小文字を区別しない)* Track.album.name.iendswith('IBU')と書くことができる
いくつかのサンプル:
1 2 3 4 5 6 7 8 9 10 11 | |
!!!ローを返さないすべてのメソッドは、QuerySetインスタンスを明示的に返すため、それらをリンクできます
1 2 3 | |
!!!警告「%ワイルドカード」は自分のために追加されたものであることに注意してください。「%」を検索値に含めると、エスケープされ、テキスト内のテキストのパーセント記号として扱われます。
除外する
exclude(*args, **kwargs) -> QuerySet
フィルターとまったく同じように動作し、すべての修飾子(接尾辞)は同じですが、not条件を返します。
したがって、filter(name='John')を使用すると、SQLのwhere name='John'に等しくなります。
条件は全て連結しているので、複数の値を渡すと条件和集合になるので注意してください。
除外(name='John', age>=35)は where not (name='John' and age>=35)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
複雑なフィルタ(ORを含む)
デフォルトでは、filter()メソッドとout()メソッドの両方が、filter(name="John", age__gt=30) を WHERE name = 'John' AND age > 30 に変換するためのAND条件とともに提供されるフィルタオプションを組み合わせます。
時には、WHERE name = 'John' OR age > 30 のように組み合わせて適用すべきではない条件クエリデータベースを使用したり、より制御したい複雑なwhereクエリを構築したりすると便利です。結局のところ、WHERE (name = 'John' OR age > 30) and city='New York' は WHERE name = 'John' OR (age > 30 and city='New York') とはまったく異なります。
ORとネストされた条件をビルドするために、ormarはQuerySetとQuerysetProxyのfilter()とout of()で使用できる2つの関数を提供します。
!!!noteこれらのメソッドは、*argsを受け入れる他のメソッド(get()やall()など)で提供できることに注意してください。
or_とand_の呼び出しは、互いに入れ子にしたり、キーワード引数と組み合わせたりすることができます。実際よりも複雑に聞こえるので、いくつかの例を見てみましょう。
このようなサンプルモデルが与えられた場合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
いくつかのサンプルデータを作成してみましょう。
1 2 3 4 5 6 7 | |
いくつかのサンプルを構築できます。
トールキンの本か1970年以降に書かれた本を選びましょう
SQL: WHERE ( authors.name = 'J.R.R. Tolkien' OR books.year > 1970 )
ジャンゴスタイル
1 2 3 4 5 6 | |
Pythonスタイル
1 2 3 4 5 6 | |
ここで、トールキンが1960年以降または1940年以前に書いた本を選択します。
SQL: WHERE ( books.year > 1960 OR books.year < 1940 ) AND authors.name = 'J.R.R. Tolkien'
ジャンゴスタイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Pythonスタイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
2000年以前のサプコフスキーの本や1960年以降のトルキンの本
SQL: WHERE ( ( books.year > 1960 AND authors.name = 'J.R.R. Tolkien' ) OR ( books.year < 2000 AND authors.name = 'Andrzej Sapkowski' ) )
ジャンゴスタイル
1 2 3 4 5 6 7 8 9 10 11 | |
Pythonスタイル
1 2 3 4 5 6 7 8 9 | |
もちろん、これらの関数は2つ以上の条件を持つことができるので、「hobbit」の本を含めたい場合は:
SQL: WHERE ( ( books.year > 1960 AND authors.name = 'J.R.R. Tolkien' ) OR ( books.year < 2000 AND os0cec_authors.name = 'Andrzej Sapkowski' ) OR books.title LIKE '%hobbit%' )
ジャンゴスタイル
1 2 3 4 5 6 7 8 9 10 11 | |
Pythonスタイル
1 2 3 4 5 6 7 8 9 | |
必要に応じて、次のクエリを実装するなど、必要に応じてより深い条件をネストできます。
SQL:
1 2 3 | |
クエリは次のように構築できます。
ジャンゴスタイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Pythonスタイル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
これで、ormar. or_とormar.and_がどのように動作するかを理解したはずです。もちろん、それらをクエリセットの他のメソッドにリンクすることもできるので、例では、完全に有効なクエリは次のようになります。
1 2 3 4 5 6 7 8 9 10 11 | |
Pythonスタイルのリンクやネストについても同様です。
ジャンゴスタイル
注意点としては、djangoスタイルでは同じキーワード引数を複数回指定することはできないため、以下のような filter(ormar.or_(name='Jack', name='John')) のクエリは許可されません。同じカラムの値を複数チェックしたい場合は、in演算子:filter(name__in=['Jack','John']) を使うだけです。
引数を1つだけor_またはand_関数に渡すと、括弧で囲まれているだけで、実際のクエリには影響しないため、最終的には3つのクエリすべてが同じになります。
1 2 3 | |
!!!note注意or_とand_のクエリにはWHERE(title='The Hobbit')がありますが、括弧は不要で実際の効果はありません。
どうしても同じフィールド名を2回使う必要がある場合は、この機能を使うことができます。同じキーワード引数を関数に2回渡すことはできないので、サンプルで WHERE (authors.name LIKE '%tolkien%') OR (authors.name LIKE '%sapkowski%')) をクエリする方法を覚えておいてください。
あなたはこれを行うことはできません:
1 2 3 4 5 6 7 8 | |
しかし、あなたはそれを行うことができます:
1 2 3 4 5 6 7 8 9 | |
Pythonスタイル
Pythonスタイルでは、同じフィールドを何度でも使用できることに注意してください。
1 2 3 4 5 6 7 8 | |
得る
get(*args,**kwargs)->モデル
kwargsの設定条件を満たす最初の行をデータベースから取得します。
任意のargsおよび/またはkwargsを渡す場合、filter(*args,**kwargs). get()を呼び出すのと同等のショートカットです
!!!tipフィルターの詳細については、フィルターを参照してください。
1 | |
取得またはなし
上記のgetとまったく同じですが、条件に一致するデータベースレコードが見つからない場合は例外をスローする代わりにNoneを返します。
取得または作成
get_or_create(_defaults: Optional[Dict[str, Any]] = None, *args, **kwargs) -> Tuple[Model, bool]
メソッドの作成と取得の組み合わせです。
これは、任意のargsやkwargsを渡すときに呼び出すのと同じショートカットです filter(*args, **kwargs).get_or_create()
!!!tipフィルターの詳細については、フィルターを参照してください。
1 | |
!!!警告指定されたアイテムが存在しない場合、(自動増分でない限り)Prime_keyカラムを含むがこれらに限定されない、モデルのすべての必須フィールドにkwargsを渡す必要があります。
全部
all(*args, **kwargs) -> List[Optional["Model"]]
設定されたフィルターオプションの場合、特定のモデルのデータベース内のすべてのローが返されます。
kwargsを渡すときは、filter(*args,**kwargs). all()を呼び出すのと同じショートカットです
!!!tipフィルターの詳細については、フィルターを参照してください。
1 | |
QuerysetProxyメソッド
関連するManyTomanyフィールドとReverseForeignKeyに直接アクセスする場合は、関連するモデルのリストを返します。
ただし、QuerySet APIのサブセットを公開しているため、親モデルから直接フィルタリング、作成、関連モデルの選択などを行うことができます。
フィルタリング
上記のフィルタリング機能と全く同じですが、関連するオブジェクトをリレーションシップの反対側からフィルタリングすることができます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください
除外する
上記の除外機能とまったく同じですが、関係の反対側から関連オブジェクトをフィルタリングすることができます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください
得る
上記のget関数と全く同じですが、関連するオブジェクトをリレーションの反対側からフィルタリングすることができます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください
取得またはなし
上記のgetとまったく同じですが、条件に一致するデータベースレコードが見つからない場合は例外をスローする代わりにNoneを返します。
取得または作成
上記のget_or_create関数と全く同じですが、関連するオブジェクトをリレーションシップの反対側からフィルタリングすることができます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください
全部
上記のすべての機能とまったく同じですが、関係の反対側から関連するオブジェクトをフィルタリングできます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください
並べ替え
注文の根拠
order_by(columns: Union[List, str, OrderAction]) -> QuerySet
order_by()を使用すると、選択したフィールドに基づいてデータベースの結果を並べ替えることができます。
フィールド名を持つ文字列、または異なるフィールドを持つ文字列のリストを指定できます。
SQLの並べ替えは、order_byで指定した名前の順に適用されます。
!!!tipデフォルトでは、並べ替えを指定しないか、すべてのプライマリキーで明示的に並べ替えます
!!!警告ネストされたモデルでソートすると、結果行がメインモデルでソートされなくなります。そうしないと、marはこれらのサブ行をメインモデルにマージします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
与えられたサンプルモデルは次のとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | |
マスターモデルフィールドで並べ替えるには、フィールド名を指定するだけです
ジャンゴスタイル
1 2 3 4 5 6 | |
Pythonスタイル
1 2 3 4 5 6 | |
ネストされたモデルを並べ替えるには、dunder'__'でフィールド名を区切ります。
このようにして、すべてのリレーションシップタイプ->ForeignKey、逆仮想FK、およびManyTomanyフィールドを並べ替えることができます。
ジャンゴスタイル
1 2 3 4 | |
Pythonスタイル
1 2 3 4 | |
降順で並べ替えるには、フィールド名の前にハイフンを付けます
ジャンゴスタイル
1 2 3 4 5 6 7 8 | |
Pythonスタイル
1 2 3 4 5 6 7 8 | |
!!!ローを返さないすべてのメソッドは、QuerySetインスタンスを明示的に返すため、それらをリンクできます
1 2 3 | |
ormarのデフォルトのソート
データベース内の行の順序は保証されていないため、自分で順序を指定しなくても、ormarは常に各(部分的な)クエリにorder by sql句を発行します。
デフォルトでは、指定されたモデルを使用してデータベースにクエリを実行する場合、モデルはPrime_keyカラムの昇順でソートされます。デフォルトの動作を変更するには、ormar_configにorder_byパラメータを指定します。
!!!ヒントモデルの並べ替え順序の詳細については、ドキュメントのモデルセクションを参照してください
デフォルトでは、リレーションシップは同じ順序に従いますが、オーダー_byおよび関連する_order_byパラメーターをリレーションシップに提供することで、クエリ中に関連するモデルがロードされる順序を変更できます。
!!!ヒントモデルの並べ替え順序の詳細については、ドキュメントのリレーショナルセクションを参照してください
order_by句の適用順序は以下の通りです:
- クエリでorder_by()呼び出しを明示的に渡す
- オーダー\byと関連するオーダー\by(存在する場合)による関係
- モデルのormar_configオブジェクトorder_by
- モデルの主要な_keyカラムの昇順(バックアップ、上記のいずれも提供されていない場合に使用)
1つのソースからの注文のみが各モデルに適用されます(単一のクエリで常に上書きできるように)。
つまり、クエリでモデルに明示的なorder_byを指定すると、リレーションシップとモデルのソート順序がスキップされます。
リレーションシップ1を指定すると、モデルの並べ替えはスキップされます。
最後に、Modelに提供した場合、主_keyのデフォルト値はスキップされます。
QuerysetProxyメソッド
関連するManyTomanyフィールドとReverseForeignKeyに直接アクセスする場合は、関連するモデルのリストを返します。
ただし、QuerySet APIのサブセットを公開しているため、親モデルから直接フィルタリング、作成、関連モデルの選択などを行うことができます。
注文の根拠
上記のorder_by関数と全く同じですが、関連するオブジェクトをリレーションの反対側からソートすることができます。
!!!ヒントQuerysetProxyの詳細については、querysetproxyセクションにアクセスしてください