NoReverseMatch at /polls/〉 为什么第 0 行会出现错误?

NoReverseMatch at /polls/ Why does error happen at line 0?

我正在制作一个网站,看到 Django tutorial.I 出错了, /polls/ 的 NoReverseMatch 找不到 'detail' 的反向。 'detail' 不是有效的视图函数或模式名称。有人说

Error during template rendering
In template /Users/xxx/djangostudy/templates/base.html, error at line 0
Reverse for 'detail' not found. 'detail' is not a valid view function or pattern name.

我真的不明白为什么第0行会出错。 base.html(在模板文件夹中)是

{% load staticfiles %}
{% load bootstrap3 %}
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Starter Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
    <style type="text/css">
body {
  padding-top: 50px;
}
    </style>
  </head>

  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="{% url 'index' %}">Tutorial</a>
        </div>
        <div id="navbar" class="collapse navbar-collapse">
          <ul class="nav navbar-nav">
            <li class="{% block nav_polls %}{% endblock %}"><a href="{% url 'polls:index' %}">polls</a></li>
            <li class=""><a href="{% url 'admin:index' %}">admin</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>

    <div class="container">
    {% bootstrap_messages messages %}
    {% block contents %}{% endblock %}
    </div><!-- /.container -->
    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery.min.js"><\/script>')</script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
  </body>
</html>

index.html(在投票中)是

{% extends "polls/base.html" %}
{% load staticfiles %}
{% block contents %}
  <table border="1" class="table table-striped">
      <tr>
          <th>質問内容</th>
          <th>公開日</th>
          <th></th>
      </tr>
          {% for question in questions %}
      <tr>
         <td>{{ question.question_text }}</td>
         <td>{{ question.pub_date }}</td>
         <td><a href="{% url 'polls:detail' question.pk %}">詳細画面へ</a></td>
      </tr>
      {% endfor %}
  </table>
{% endblock contents %}

'detail'表示detail.html,即

<!DOCTYPE html>
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'poll_vote' question.id %}" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Vote" />
</form>
</html>

我认为错误消息意味着 index.html 无法加载 detail.html。所以,我想这样做,但我不知道该怎么做 it.Sould 我在第 0 行写了一些东西 [= =40=]?

views.py 在民调中是

from django.shortcuts import render
from django.urls import reverse_lazy
from django.utils.html import mark_safe
from .models import Question
from django.http import HttpResponse
from django.shortcuts import Http404
from django.shortcuts import get_object_or_404,redirect
from .models import Choice
from django.views.generic import TemplateView
from django.views.generic import DetailView
from django.views.generic import ListView
from .forms import MyForm
from .forms import VoteForm
from django.views.generic import FormView
from django.views.generic.detail import SingleObjectMixin
from django.shortcuts import resolve_url



# Create your views here.
def index(request):
    return render(request,'polls/index.html',{
        'questions': Question.objects.all(),
    })

# def detail(request,pk):
#     obj = get_object_or_404(Question,pk=pk)
#     if request.method == "POST":
#         form = VoteForm(question=obj,data=request.POST)
#         if form.is_valid():
#             form.vote()
#             return redirect('polls:results',pk)
#     else:
#         form = VoteForm(question=obj)
#     return render(request,'polls/detail.html',{
#         'form':form,
#         'question': obj,
#     })

def vote(request,pk):
    question = get_object_or_404(Question,pk=pk)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError,Choice.DoesNotExist):
        return render(request,'poll/detail.html',{
            'question':question,
            'error_message':"You didn't select a choice",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return redirect('index')
    return redirect('poll_results', pk)
    # pass

def results(request,pk):
    obj = get_object_or_404(Question,pk=pk)
    return render(request,'polls/results.html',{
        'question':obj,
    })

class FormTest(FormView):
   form_class = MyForm
   template_name = 'polls/form.html'
   success_url = reverse_lazy('polls:index')
form_test = FormTest.as_view()

class Detail(SingleObjectMixin,FormView):
    model = Question
    form_class = VoteForm
    context_object_name = 'question'
    template_name = 'polls/detail.html'

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super().post(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super().post(request, *args, **kwargs)

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['question'] = self.object
        return kwargs

    def form_valid(self, form):
        form.vote()
        return super().form_valid(form)

    def get_success_url(self):
        return resolve_url('polls:results',self.kwargs['pk'])

detail = Detail.as_view()

urls.py 在民调中是

from django.conf.urls import url
from django.views.generic import TemplateView
from . import views

app_name="polls"
urlpatterns = [
    url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
    url(r'(?P<pk>\d+)/vote$', views.vote, name='poll_vote'),
    url(r'(?P<pk>\d+)/results$', views.results, name='poll_results'),
    url(r'^$',views.index,name='index'),
    url(r'^form$', views.form_test),
]

目录是

我该如何解决这个问题?

你打错了:

<a href="{% url 'polls:detail' question.pk %}">

<a href="{% url 'polls:poll_detail' question.pk %}">
 <!--                 ^^^^^^^  -->

{% url %} 接受在 urlpatterns 中定义的 URL 的 名称,最终对应于一个视图。这与 detail.html 是否存在无关,您不能 link 直接到 detail.html 因为您需要一个说明如何呈现它的视图。

使用 {% url 'poll_detail' ... %} 因为这是您命名视图的方式。

在此处查看文档:https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#url

<td><a href="{% url 'polls:detail' question.pk %}">詳細画面へ</a></td> 

必须在djangostudy中修改urls.py才能使用

按照 urls.py 中指定的命名空间或使用 polls/urls.py

中指定的名称“poll_detail”

请注意,polls:This 指定为命名空间,poll_detail 由名称指定。