2011-01-04 24 views
1

Djangoのpaginatorモジュールの仕組みと最適化方法について質問があります。私はインターネット上のさまざまなAPIから得た情報から約300項目のリストを持っています。私はDjangoのpaginatorモジュールを使用して、訪問者のリストを一度に10項目ずつ表示しています。ページネーションは私が望むだけでは機能しません。ペイジネータは、ページが変更されるたびに表示する必要がある10個を引き出す前に、300個のアイテムすべてを取得しなければならないようです。たとえば、30ページがある場合、ページ2に行くと、私のウェブサイトにAPIを再度照会し、すべての情報をリストに入れてから、ビジターのブラウザが要求する10個の情報にアクセスする必要があります。私は、各ページのターンで既に持っているのと同じ情報のためにAPIを照会し続けたくありません。Djangoのpaginatorモジュールの最適化方法

現在のところ、私のビューにはget要求を見て、クエリに基づいて情報をAPIに問い合わせる機能があります。次に、すべての情報をリストに入れ、それをテンプレートファイルに渡します。そのため、誰かがページをめくるたびにこの関数が常にロードされ、結果的にAPIのクエリが実行されます。

これはどのように修正する必要がありますか?

ありがとうございました。

答えて

1

この場合、ページ処理担当者はその仕事をするために完全なリストを必要とします。

私の助言は、定期的な間隔でフィードのキャッシュを更新し、そのキャッシュをページングモジュールへの入力として使用することです。それぞれの要求に対して集中的な作業や長時間の作業を行うことは、常に悪い考えです。ユーザーが経験するページの読み込み時間でない場合は、攻撃するサーバーの脆弱性を考えます。

Django's low level cache APIをチェックすると、キーの下にあるグローバルにアクセス可能な場所にフィード結果を保存できます。このキーを使用して、各ページリクエストごとにキャッシュとページングを取得できます。

query_results = Foo(id=1) # No sql executed yet, just stored. 

foo = query_results[0] # now it fires 

または

for foo in query_results: 
    foo.bar() # sql fires 

を使用すると、初期化時に結果をロードしているカスタムデータソースを使用している場合、ページ区切りが動作しません:行が選択されるまでのデータをロードしていない

+2

説明を追加するだけで、データベースからDjango ORMを介してアイテムを取得する場合、paginatorは必要なアイテムだけを正しく照会し、合計を取得するだけのカウントを行います。しかし、他の場所からデータを取得している場合は、実際にすべてを取得する必要があります。 –

0

ORMすべてのフィードが一度に取得されるため、期待どおりに処理されます。実際のフェッチを行うには、__getitem__または__iter__をサブクラス化するとよいでしょう。これは、Djangoが結果をロードする方法と一致します。

ページネーションは、has_next()のような結果がいくつあるかを知る必要があります。 SQLではインデックスを持つcount(*)を入手するのが安価です。だから、あなたはまた、結果が何通りあるかを知りたい(あるいは、正確に知るには高価すぎるかどうかを推定するだけかもしれない)。

関連する問題