時々djangoコードを読むと、いくつかのテンプレートに表示されreverse()
ます。これが何であるかはよくわかりませんが、HttpResponseRedirectと一緒に使用されます。これはいつどのようにreverse()
ように使用されることになっていますか?
誰かがいくつかの例を挙げて答えを出すといいですね...
時々djangoコードを読むと、いくつかのテンプレートに表示されreverse()
ます。これが何であるかはよくわかりませんが、HttpResponseRedirectと一緒に使用されます。これはいつどのようにreverse()
ように使用されることになっていますか?
誰かがいくつかの例を挙げて答えを出すといいですね...
回答:
あなたの中でurls.py
これを定義したとしましょう:
url(r'^foo$', some_view, name='url_name'),
テンプレートでは、このURLを次のように参照できます。
<!-- django <= 1.4 -->
<a href="{% url url_name %}">link which calls some_view</a>
<!-- django >= 1.5 or with {% load url from future %} in your template -->
<a href="{% url 'url_name' %}">link which calls some_view</a>
これは次のようにレンダリングされます:
<a href="/foo/">link which calls some_view</a>
ここで、同じようなことをしたいとしますviews.py
-たとえば/foo/
、他のビュー(ではない)で他のURL(ではない)を処理していてsome_view
、ユーザーをリダイレクトしたい/foo/
場合(多くの場合、フォームの送信が成功した場合)。
あなたはただ行うことができます:
return HttpResponseRedirect('/foo/')
しかし、将来URLを変更したい場合はどうでしょうか?あなたは更新する必要があるだろうurls.py
し、あなたのコード内のそれへのすべての参照を。これはDRY(Do n't Repeat Yourself)に違反していますにしています。これは、1か所だけを編集するという全体的な考えです。
代わりに、次のように言うことができます。
from django.urls import reverse
return HttpResponseRedirect(reverse('url_name'))
これは、プロジェクトで定義されたすべてのURLを調べて、名前で定義されたURLを探しurl_name
、実際のURLを返します/foo/
。
これは、そのname
属性によってのみURLを参照することを意味します。URL自体またはURLが参照するビューを変更する場合は、1つの場所のみを編集することでこれを行うことができますurls.py
。
url_reverse
。これらの種類の奇妙な点に対処する最善の方法は、それらの使用を拒否することです。
これは古い質問ですが、これは誰かを助けるかもしれないものです。
公式ドキュメントから:
Djangoは、URLが必要なさまざまなレイヤーに一致するURL反転を実行するためのツールを提供します。テンプレート内:urlテンプレートタグを使用します。Pythonコード:reverse()関数の使用。DjangoモデルインスタンスのURLの処理に関連する上位レベルのコード:get_absolute_url()メソッド。
例えば。テンプレート内(URLタグ)
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
例えば。Pythonコードで(reverse
関数を使用)
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
既存の答えは これの何を説明するのに素晴らしい仕事をしましたreverse()
Django機能がに役立ちました。
しかし、私は私の答えはで異なる光を当てることが期待のだ理由:使用する理由reverse()
テンプレートビューで他のより直接的な、間違いなくより多くのニシキヘビのアプローチの代わりには、結合、およびこの「リダイレクトの人気のためにいくつかの正当な理由どのようなものを経由して reverse()
Djangoルーティングロジックの「パターン」。
他の人が述べたように、1つの重要な利点は、URLの逆構築です。ちょうどあなたが使用する方法のような{% url "profile" profile.id %}
例:アプリケーションのURL設定ファイルからURLを生成しますpath('<int:profile.id>/profile', views.profile, name="profile")
。
しかし、OPが指摘したように、の使用reverse()
は通常、の使用とも組み合わされますHttpResponseRedirect
。しかし、なぜ?
これが何であるかはよくわかりませんが、HttpResponseRedirectと一緒に使用されます。このreverse()はいつどのように使用されることになっていますか?
以下を検討してくださいviews.py
。
from django.http import HttpResponseRedirect
from django.urls import reverse
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected = question.choice_set.get(pk=request.POST['choice'])
except KeyError:
# handle exception
pass
else:
selected.votes += 1
selected.save()
return HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
))
そして私たちの最小限urls.py
:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-results'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
ではvote()
機能、私たちの内のコードelse
ブロックを使用していますreverse
と一緒にHttpResponseRedirect
以下のパターンで:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
これは何よりもまず、URLをハードコーディングする必要がないことを意味します(DRYの原則に準拠)。ただし、より重要なのreverse()
は、引数からアンパックされた値を処理することによってURL文字列を作成するエレガントな方法を提供します(args=(question.id)
URLConfigによって処理されます)。に値を含むquestion
属性があるとするid
と5
、から構成されるURL reverse()
は次のようになります。
'/polls/5/results/'
通常のテンプレートとビューのバインディングコードでは、以下の抽象化を使用するHttpResponse()
かrender()
、通常は抽象化が少なくなります。1つのテンプレートを返す1つのビュー関数:
def index(request):
return render(request, 'polls/index.html')
しかし、リダイレクトの多くの正当なケースでは、通常、パラメーターのリストからURLを構築することに関心があります。これには、次のような場合が含まれます。
POST
リクエストによるHTMLフォームの送信これらのほとんどは、なんらかの形式のリダイレクトと、一連のパラメータを介して構築されたURLを含みます。これがすでに役立つ回答のスレッドに追加されることを願っています!
関数はドライの原則をサポートします-アプリ全体でURLをハードコードしないようにします。URLは1か所で定義する必要があり、1か所のみ-URL設定です。その後、あなたは本当にその情報を参照しているだけです。
reverse()
ビューへのパス、またはurl設定からのpage_nameパラメータのいずれかを指定して、ページのURLを提供するために使用します。テンプレートでを使用しても意味がない場合に使用し{% url 'my-page' %}
ます。
この機能を使用できる場所はたくさんあります。私が見つけた1つの場所は、ビューでユーザーをリダイレクトするときです(多くの場合、フォームの処理が成功した後)。
return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))
テンプレートタグを記述するときにも使用できます。
私が使用しreverse()
たもう1つの時期は、モデルの継承です。親モデルにListViewがありましたが、それらの親オブジェクトのいずれかから、それに関連付けられている子オブジェクトのDetailViewに移動したいと考えました。get__child_url()
子の存在を識別する関数を親にアタッチし、を使用してそのDetailViewのURLを返しましたreverse()
。
そのためのドキュメントがあります
https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls
特定のビューのURLを生成するために使用できます
主な利点は、コードにルートをハードコードしないことです。
既存の答えは非常に明確です。それが呼び出される理由がわからない場合に備えてreverse
:URL名の入力を受け取り、実際のURLを取得します。これは、最初にURLを取得してから名前を付けるのとは逆です。
url--> view name
。ただし、リダイレクトの場合と同様に、逆方向に移動してDjangoにビューの名前を付ける必要がある場合があります。Djangoは適切なURLを生成します。つまり、view name --> url
です。つまり、reverse()
(これはurl関数の逆です)。ちょうどそれを呼び出すために、より透明に見えるかもしれないgenerateUrlFromViewName
:それはあまりにも長い間、おそらく一般的な十分ではありませんdocs.djangoproject.com/en/dev/topics/http/urls/...