【Django】reverseメソッドとは何が"逆"なのかしっくりこなかったので公式ドキュメント読む

# 疑問の源泉

[Djangoのチュートリアル part4 (ver2.2)](https://docs.djangoproject.com/en/2.2/intro/tutorial04/)で初出の `django.urls.reverse` メソッド。(以下最終行)


```python:polls/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse

from .models import Choice, Question
# ...
def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
```

最終行の `reverse('polls:results', args=(question.id,))` は、以下`view.py`の4行目と紐づいてリダイレクトURLが生成されクライアントへ返されるんだろうな、ということは分かるんですが、、、

```python:polls/urls.py
urlpatterns = [
    path('', views.index, name='index'),
    path('\<int:question_id>/', views.detail, name="detail"),
  ★path('\<int:question_id>/results/', views.results, name="results"),
    path('\<int:question_id>/vote/', views.vote, name="vote")
]
```

**なんで reverse？ 何を"逆"にしているんだろう？何かひっくり返してる？**
**"逆"ではない"順"は何なのだろう？**

という疑問が浮かびこのコードが頭にスッと入ってこない。というのが発端です。

というのも、直前まで触っていたFlaskだと `redirect(url_for('polls.results'))` のように書けて、resultsへのURLを生成、という風に読んで字のまま直感で分かりやすかったのでなおさら「Djangoはなんでここでreverseなんだ」と。

## 調べた方法：公式ドキュメント内で"reverse"と検索
![2020-01-29_10h31_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283290/e66bc901-1467-e7f6-0c7b-5d45de430fae.png)

パッと見それっぽいリンクが2つ見つかったので、この２つをざっと読みました。

が、[django.urls utility functions](https://docs.djangoproject.com/en/2.2/ref/urlresolvers/) の方はメソッドの定義で「あぁ、それでreverse/逆なのか」とピンとこず。

[URL Dispatcher](https://docs.djangoproject.com/en/2.2/topics/http/urls/)  を読んでみると、イメージできるようになりました。

## URL->viewの解決が"順"、view->URLの解決が"逆"

>Django provides a solution such that the URL mapper is the only repository of the URL design. You feed it with your URLconf and then it can be used in both directions:
>
- **Starting with a URL requested by the user/browser, it calls the right Django view** providing any arguments it might need with their values as extracted from the URL.
- **Starting with the identification of the corresponding Django view** plus the values of arguments that would be passed to it, **obtain the associated URL.**

>The first one is the usage we’ve been discussing in the previous sections. **The second one is what is known as reverse resolution of URLs, reverse URL matching, reverse URL lookup, or simply URL reversing**.

上記引用の太字部分から、

- ユーザからサーバへのリクエスト ＝ URLをもとに対応するviewを見つける ＝ `URL -> view` ＝ これが"順"
- viewをもとに対応するURLを見つける ＝ `view -> URL` ＝ これが"逆"

ということが分かりました。

正直、URL ⇔ ビュー間の正引き/逆引きという概念を全く意識しておらずごっちゃにしていました。
Pythonの Explicit is better な精神を垣間見た気がします。