2012-03-06 12 views
7

私はいくつかの外部キーフィールドを持つモデルを持っています。 'タイプ'、 'レベル'、 '色'、 '強度'のフィールド(一般的な例)を持つモデル製品。Djangoインラインformsetsとchoicefieldsが多すぎるdbクエリを生成します。

次に、インラインフォームセットとして製品を含むタイプフォームとextra=10を使用して製品をインラインで追加するオプションを使用して、特定のタイプのすべての製品を編集するページがあります。

私が非常に奇妙なことは、毎回、テンプレート上の外部キー選択フィールドの1つを出力するときに、オプションを取得する(毎回)データベースを照会するということです。例えば

:20の製品(10空の余分な形態)で

{% for form in formset %} 
    {{ form.level }} 
    {{ form.color }} 
    {{ form.intensity }} 
{% endfor %} 

上記のコードは90個のクエリを集計レベル、色及び強度から30 select * from ...を発行する(ジャンゴデバッグツールバーを使用して明らかにした)は、3十分でなければならない。オプションは途中のリクエストを変更する可能性はほとんどありませんが、そうしたとしても、新しく追加されたオプションが最後の5つのフォームにのみ表示されることは間違いありません。

モデル/フォーム/ビュー/テンプレートを最適化して、データベースがこれを不必要にハンマーにならないようにする方法はありますか?

-

免責事項:私はジャンゴとPythonのは比較的新しいですし、これは何とかして構築された対処する方法がなければならない思考を助けることはできません。

答えて

4
field_queryset = Test.objects.all()  
for form in formset: 
     form.fields['test_field'].queryset = field_queryset 

このようにします。

+0

Nice Denisは意味があります。すべて同じクエリーセットオブジェクトを使用するようにしてください。あなたは11ヶ月間答えてチャイムに入り、それを受け入れるためにもう8ヶ月もかかりました。ちょうど 'タイプ'、 'レベル'、 '色'タイプを完全にキャッシュすることによってこれを対処しました。これらは変わらないかなりの定数です。しかし、ありがとう、これは私が次回に心に留めておく簡単なアプローチです。 – davur

+0

これは動作しません。これらのフォームは、デフォルトのクエリーセットで構築されてから、このように置き換えることができます。 –

+1

@Adrián、実際には「はい、いいえ」と思います。あなたが正しいです、既定のクエリセットはおそらくFormコンストラクタで作成されます。ただし、クエリーセットの作成は、データベースのクエリーと同じではありません。最初のクエリーが発行される前にクエリーセットを交換すると、不要なコールをすべてデータベースに保存することができます。最初のフォームをテンプレートに表示する前に、各フォームで 'save'を呼び出す前に、これらを置き換える必要があります。 – davur

1

change the queryset used by the formsetとすることができます。その後、各forループの繰り返しでクエリを実行するのではなく、select_related()を使用してFK結合を生成できます。

+1

この状況でこれらがどのように役立つかわかりません。クエリーセットは製品の現在の値を選択するためのもので、select_relatedは現在各製品にリンクされているレベル/色/強度のオブジェクトをフェッチするのに役立ちます。 select_relatedは実際にselectオプションのセット全体をプリフェッチする際に実際にどのように役立ち、selectボックスに値を設定しますか? – davur

+0

だから、ajaxオートコンプリート(django-ajax-select)を使うか、クエリキャッシュ(johnnycache)を使うかどちらかを使うことができます。 – jpic

関連する問題