[解決済み] Django のビューで 2 つ以上のクエリセットを結合するにはどうすればよいですか?
質問
私が構築している Django サイトの検索を構築しようとしているのですが、その検索では、3つの異なるモデルで検索しているのです。そして、検索結果リストのページネーションを得るために、汎用的な object_list ビューを使って結果を表示したいのです。しかし、それを行うには、3つのクエリセットを1つにマージする必要があります。
どうすればいいのでしょうか?私はこれを試してみました。
result_list = []
page_list = Page.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term))
article_list = Article.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term) |
Q(tags__icontains=cleaned_search_term))
post_list = Post.objects.filter(
Q(title__icontains=cleaned_search_term) |
Q(body__icontains=cleaned_search_term) |
Q(tags__icontains=cleaned_search_term))
for x in page_list:
result_list.append(x)
for x in article_list:
result_list.append(x)
for x in post_list:
result_list.append(x)
return object_list(
request,
queryset=result_list,
template_object_name='result',
paginate_by=10,
extra_context={
'search_term': search_term},
template_name="search/result_list.html")
しかし、これではうまくいかない。そのリストを汎用ビューで使おうとすると、エラーが発生します。このリストにはclone属性がありません。
3つのリストを統合するにはどうすればよいですか。
page_list
,
article_list
と
post_list
?
解決方法は?
クエリセットをリストに結合するのは、最もシンプルな方法です。もしデータベースがすべてのクエリセットに対してヒットするのであれば(例えば、結果をソートする必要があるため)、これはさらなるコストを増加させないでしょう。
from itertools import chain
result_list = list(chain(page_list, article_list, post_list))
使用方法
itertools.chain
は、各リストをループして要素を1つずつ追加するよりも高速です。
itertools
また、各クエリセットをリストに変換してから連結するよりも少ないメモリ消費量で済みます。
これで、結果のリストを例えば日付でソートすることが可能になりました(別の回答に対するhasen jさんのコメントで要望がありました)。その
sorted()
関数は、ジェネレータを受け取り、リストを返すという便利なものです。
result_list = sorted(
chain(page_list, article_list, post_list),
key=lambda instance: instance.date_created)
Python 2.4以降を使用している場合は、Python 2.4以降を使用している場合は、以下のように
attrgetter
ラムダの代わりに 高速化されるという記事を読んだ記憶がありますが、100万アイテムのリストでは目立った速度差は感じられませんでした。
from operator import attrgetter
result_list = sorted(
chain(page_list, article_list, post_list),
key=attrgetter('date_created'))
関連
-
[解決済み】Djangoのクエリセットフィルタリングでnot equalを行うにはどうすればよいですか?
-
[解決済み】djangoのビジネスロジックとデータアクセスの分離
-
[解決済み] Django REST Framework: ModelSerializerに追加フィールドを追加する
-
[解決済み] Django Admin - 特定のモデルに対して 'Add' アクションを無効にする
-
[解決済み] Django REST フレームワーク: 非モデルシリアライザー
-
[解決済み] Djangoです。文字列からモデルを取得する?
-
[解決済み] Django の filter と get は単一オブジェクトの場合?
-
[解決済み] Django テンプレート url タグに url パラメータを追加する方法は?
-
[解決済み] Django - 外部キーのプロパティでフィルタリングする
-
[解決済み] egg_infoエラーでpipからインストールできない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
6.5、Django - モデルでJSONFieldを使用してJSONフィールドでMySQLテーブルを作成する
-
Django。"makemigrations "時に変更が検出されない。
-
[解決済み] Django の管理者パスワードをリセットする方法は?
-
[解決済み] FastCGIとDjangoを使用しているnginxのエラーログはどこで見ることができますか?
-
[解決済み] django-rest-framework の管理者スタイルのブラウズ可能なインターフェイスを無効にする方法は?
-
[解決済み] Django は単一のモデルに対してデータをダンプしますか?
-
[解決済み] models.pyでDjangoの設定変数を参照するには?
-
[解決済み] Djangoのデータベースクエリ。id でオブジェクトを取得するには?
-
[解決済み] テーブルのフィールドから異なる値を選択する
-
[解決済み] dbなしのdjangoユニットテスト