5

問題は、テンプレートタグをブロックに呼び出して、通常の context[varname]=something で変数を埋めた場合、その変数を別のブロックに必要とする場合、テンプレートタグを再度呼び出さなければならないことです。これは、余分な db クエリを意味します。これは、私が避けようとしているものです。

この templatetag は、他の多くのテンプレートによって拡張される基本テンプレートで呼び出されるため、すべてのビューを変更してコンテキストに何かを渡すことはできません。意味がありません (WET 原則?)

そのテンプレートに基づいていないものであっても、サイトでレンダリングされるすべてのページに対して呼び出したくないので、コンテキスト プロセッサでさえ良くありません。

内部コンテキスト構造を使用して変数をグローバル コンテキストに配置する templatetag を作成することを考えていましたが、それを行うのは罪悪感が強すぎます。

この問題をどのように解決しますか?

4

4 に答える 4

3

「このテンプレートタグは、他の多くのテンプレートによって拡張された基本テンプレートで呼び出されます」とあなたは言いました。

問題は、このタグが名前付きブロック内から呼び出されているかどうかです。そうであれば、潜在的な問題がいくつかあります。

  1. {% block %}コンテキスト スタックに新しい dict をプッシュし、一致する `{% endblock %}' に到達するとポップします。これは、ブロック内で作成されたコンテキスト値が、基本的にブロックの終了時に範囲外になったことを意味します。

  2. このブロックがベース テンプレートを拡張する他のテンプレートによってオーバーライドされた場合、 を実行しない限り、値がまったく利用できない可能性があります{{block.super}}

タグがa 内から呼び出されない{% block %}場合、コンテキスト値は、それに続くすべてのコード (基本テンプレート、含まれるテンプレート、および (私が思うに) 拡張テンプレートのいずれか) で使用できる必要があります。

これは、一連の慎重なテストを作成することで、おそらく時間と労力を節約できるケースの 1 つです。

または、常にこの値にアクセスしている場合は、コンテキスト プロセッサに配置して、その可用性が保証されるようにすることもできます。

コメントの更新: OK、大砲を持ち込む時が来ました! Django テンプレートの最もいらいらする長年のバグの 1 つは、トップレベルのコンテキスト値である呼び出し可能オブジェクト (つまり、関数) (コンテキスト値の辞書値/メソッドである関数とは対照的に)が呼び出されないことです! このチケットは 2 年以上前のもので、修正には約 10 行のコードが必要です。テンプレート キャッシュの有効期限が切れた場合にのみ発生させたい重い DB 呼び出しがいくつかあります。そのため、a) テンプレート コードに MonkeyPatch を適用して呼び出し可能な問題を修正し、次に b) 必要に応じ_resolve_lookup()て必要なパラメーターをすべて持つように関数をカレー化しました。これは、テンプレート「言語」の関数にパラメーターを渡すことができないためです。

于 2010-01-16T19:10:01.707 に答える
2

この状況での制限を正確に説明したと思います。最もメンテナンスしやすいソリューションには、テンプレートの継承チェーンの再構築が含まれる可能性がありますが、詳細を知らずに言うのは難しいです。継承階層に新しいテンプレートを導入できますか?おそらくピラミッドの最上部近くにありますが、このデータを必要とするテンプレートによってのみ継承され、このデータが必要な領域全体を含む単一のブロックを使用できますか? その大きなブロックは、テンプレートを継承することでオーバーライドされる小さなブロックに分割できます。そのブロックの先頭で templatetag を呼び出すと、その中のすべてのブロック (テンプレートの継承を含む) がデータにアクセスできます。

更新: あなたのテンプレートを見ずして多くを語ることはできませんが、継承チェーンの途中で新しいテンプレートを導入する場合、「すべてのテンプレートを変更する」ことはほとんどありません。健全な継承構造では、多くの場合、1 つだけを変更するだけで済みますまたは他の 2 つのテンプレート。そして、私が提案しているのは実際にはハックではなく、より良い設計だと思います. サイトの特定の部分で特定のデータが必要で、他の部分では必要ない場合は、特定の単一のテンプレートを指定して、「このテンプレートは、このデータが導入される論理層を表し、そのデータが必要なサイトの部分。」

于 2010-01-16T20:55:02.950 に答える
0

データベースクエリの数を抑えようとしているだけですか、それとも賢い解決策を探していますか?

前者の場合、私は間違いなくキャッシングを使用します。あなたの場合、フラグメントキャッシングは機能しますか? そうでない場合は、テンプレート タグ コードにキャッシュを入れることができますか (使用している Django 独自のテンプレート タグの 1 つではないと仮定します)。

于 2010-01-16T18:11:17.750 に答える