ListViewなどを使用している時、リダイレクトURLの指定に、success_url = reverse_lazy(テンプレート名)を使用する場面があるかと思いますが、その場面で下記のようなエラーに遭遇するケースがあります。
NoReverseMatch: Reverse for ‘app/favorite_list.html’ not found. ‘app/favorite_list.html’ is not a valid view function or pattern name.
また、このエラーは下記のテンプレートのように、リダイレクトURLの指定にURLテンプレートタグを使用した場合も発生することがあります。
このエラー自体は、テンプレート名(今回の例では、’app/favorite_list.html’です。)が存在しませんというエラーです。
app/urls.py
from django.urls import path, include
from . import views
app_name = "app"
urlpatterns = [
path('', views.FavoriteCreate.as_view(), name='app/favorite_create'),
path('favorite_list/', views.FavoriteList.as_view(), name='app/favorite_list'),
]
views.py
from django.shortcuts import render
from django.views.generic import CreateView, ListView
from .models import Favorite
from .forms import FavoriteForm
from django.urls import reverse, reverse_lazy
# Create your views here.
class FavoriteCreate(CreateView):
template_name = 'app/favorite_create.html'
form_class = FavoriteForm
success_url = reverse_lazy('app/favorite_list') # <=ここが原因
class FavoriteList(ListView):
template_name = 'app/favorite_list.html'
model = Favorite
templates/favorite_create.html
<div class="container my-3 wrapper">
<div class="text-center my-3">
<h2>新しい日記</h2>
</div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">登録</button>
</form>
<a href="{% url 'app/favorite_list' %}">お気に入り一覧ページ</a> # <=ここが原因
</div>
解決法
結論から申し上げると、app/urls.pyにapp_name=”アプリケーション名”が入力されている場合、reverse系のメソッドでテンプレート名を指定する場合、下記のように引数を調整する必要があります。
reverse_lazy(“アプリケーション名:テンプレート名*”)
{% url ‘アプリケーション名:テンプレート名*’ %}
*テンプレート名は、app/urls.py内でapp_name=”テンプレート名“で指定したテンプレート名を引き渡します。
今回の例ですと、下記のように修正すれば解決します。
views.py
from django.shortcuts import render
from django.views.generic import CreateView, ListView
from .models import Favorite
from .forms import FavoriteForm
from django.urls import reverse, reverse_lazy
# Create your views here.
class FavoriteCreate(CreateView):
template_name = 'app/favorite_create.html'
form_class = FavoriteForm
success_url = reverse_lazy('app:app/favorite_list') # <= 引数を(アプリケーション名:テンプレート名)に変更する。
class FavoriteList(ListView):
template_name = 'app/favorite_list.html'
model = Favorite
templates/favorite_create.html
<div class="container my-3 wrapper">
<div class="text-center my-3">
<h2>新しい日記</h2>
</div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary form-control" type="submit">登録</button>
</form>
<a href="{% url 'app:app/favorite_list' %}">お気に入り一覧ページ</a> # 引数を(アプリケーション名:テンプレート名)に変更する。
</div>
因みに、app/urls.pyでapp_nameを設定しない場合は、通常通りreverse_lazy()の引数にテンプレート名を入力すれば動作致します。
コメント