34


4

Django:テンプレートから呼び出し元のビューを特定するにはどうすればいいですか?

短縮版:

追加のコンテキスト変数を渡さずに、Djangoテンプレート内の呼び出し元のビューを識別するための単純な組み込みの方法はありますか?

ロング(オリジナル)バージョン:

私のDjangoアプリの1つには、それぞれ独自の名前付きURLパターンを持つ複数の異なるビューがあり、それらすべてが同じテンプレートをレンダリングします。 呼び出されるビューに応じて変更する必要がある非常に少量のテンプレートコードがあります。ビューごとに別々のテンプレートを設定するオーバーヘッドに見合うには小さすぎるので、理想的にはテンプレートで呼び出しビューを識別する方法を見つける必要があります。 。

追加のコンテキスト変数を渡すようにビューを設定してみました(例: "view_name")呼び出し元のビューを識別し、 `+ {%ifequal request.path" / some / path / "%} +`比較も使用しようとしましたが、どちらのソリューションも特にエレガントではありません。 テンプレートから呼び出し側のビューを識別するもっと良い方法はありますか? ビューの名前、またはURLパターンの名前にアクセスする方法はありますか?

'' '' '

*アップデート1:*これは私がMVCを誤解しているという単なる例であるというコメントに関して、私はMVCを理解していますが、http://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be -a-mvc-framework-but-your-controller-view-and-the-view-the-template-the-template-how-you-standard-names [Django’s]実際にはMVCフレームワークではありません]。 私のアプリの設定方法はDjangoのMVCの考え方と一致していると思います。ビューはデータを表すもの、テンプレートはデータを表すものです。 異なるデータを準備するビューがいくつかありますが、データはすべてのビューに対して同じ方法で表示されるため、すべて同じテンプレートを使用します。 私はこれが存在するのであれば、テンプレートから呼び出し元のビューを識別する簡単な方法を探しています。

*更新2:*すべての回答をありがとう。 私は最初の質問で述べたように、私はすでにすべての提案された解決策を検討してみました - その質問の先頭にある「ショートバージョン」にそれを蒸留しました。 。 そして今誰かが単に "いいえ"を投稿するのであれば、それが最も正しい答えだろう:)

更新3: Carl Meyerが "いいえ"を投稿しました:)ありがとうございます。

9 Answer


20


Django 1.5以降、 `+ url_name +`は以下を使用してアクセス可能です:

request.resolver_match.url_name

その前に、ミドルウェアを使うことができます。

from django.core.urlresolvers import resolve

class ViewNameMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        url_name = resolve(request.path).url_name
        request.url_name = url_name

それから、これをMIDDLEWARE_CLASSESに追加し、そしてテンプレートに追加します。

{% if request.url_name == "url_name" %} ... {% endif %}

RequestContext(request)を考慮すると、常にrender関数に渡されます。 URLにはurl_nameを使用することを好みますが、resolve()。app_nameおよびresolve()。func.nameを使用できますが、これはデコレータでは機能しません - 代わりにデコレータ関数名が返されます。


18


いいえ、それは悪い考えです。 テンプレートからビュー関数名を直接参照することは、ビュー層とテンプレート層の間の過度に密接な結合をもたらします。

ここでもっと良い解決策はDjangoのテンプレート継承システムです。 各ビューのバージョンで変更する必要がある(小さい)領域用のブロックを使用して、共通の親テンプレートを定義します。 次に、各ビューのテンプレートを親から拡張するように定義し、そのブロックを適切に定義します。


2


Django 1.5以降、 ResolverMatchのインスタンスにhttps://docs.djangoproject.com/enからアクセスできます。 /1.9/ref/request-response/#django.http.HttpRequest.resolver_match[request.resolver_match]。

ResolverMatchはあなたに解決されたURL名、名前空間などを与えます。


1


これは、設定できる一般的なビューの完璧な例のように思えます。

以下の資料を参照してください。

これらのリンクは、それに応じてビューとテンプレートを単純化するのに役立ちます。


1


私は、各ビューを自分のcmsのヘルプページに対応させ、そのビューにヘルプページが定義されていない場合はデフォルトのページを表示するようにしたいというヘルプページシステムについて作業しています。 私は this blogテンプレートの文脈プロセッサを使うところでつまずいた。そしていくつかのpythonはビュー名を推測してそれにコンテキストを追加するために魔法を調べます。


1


あなたの名前付けがあなたのurls.pyとviews.pyで一致しているなら(それはそうあるべきです)、これはビュー名を返すでしょう:

{{request.resolver_match.url_name}}

テンプレートで呼び出すときは、必ず何らかのコンテキストを適用してください。 たとえば、ここでは詳細ビューから削除ボタンを削除するために使用しますが、更新ビューでも削除ボタンは表示されます。

{%if request.resolver_match.url_name!= 'employee_detail'%}


0


一つの簡単な解決策は:

def view1(req):viewname = "view1"そしてこのビュー名をテンプレートコンテキストに渡す

def view2(req):viewname = "view2"そしてこのビュー名をテンプレートコンテキストに渡す

テンプレート内でビュー名に次のようにアクセスします。

{{viewname}}

また、これを比較に使用することもできます。


0


ほとんどの汎用ビューは、すべてではないにしても、 + view +を追加するhttps://docs.djangoproject.com/en/1.9/ref/class-based-views/mixins-simple/#contextmixin [ + ContextMixin + `]を継承します`Viewインスタンスを指すコンテキスト変数。


-1


セッションCookieを設定してからテンプレートからCookieを読み取ってみませんか。

あなたの意見にクッキーを設定する

def view1(request):... #set cookie request.session ["param"] = "view1"

def view2(request):request.session ["param"] = "view2"

それならあなたの1つのテンプレートの中で何かをチェックしてください。

{%ifequal request.session.param "view1"%} ... view1に関連することをする{%endifequal%}

{%ifequal request.session.param "view2"%} ... "view2"に関連することをする{%endifequal%}

ガト