I have fought this for a week before coming humbly to ask for some help. I did a lookup on tutorial 4, then NoReverseMatch but the search didn’t yield any workable hints after reading the results that turned up.
I added Choice to the admin.py to see if any database errors might exist, but didn’t turn up any. I only have a single question with 3 choices.
Prior to the changes to the view.py and the urls.py shown here, I was getting the same error on line 16 but the exception was saying the dictionary values returned were empty.
NoReverseMatch at /polls/1/ at line 16 in the detail.html is the primary error for before I made the last changes in tutorial 4. ( I know, the definition of insane is repeating the error numerous times … I admit it.)
If any pertinent file is missing, let me know.
Error during template rendering
In template /home/dglenn/Projects/Django/innotest/polls/templates/polls/detail.html, error at line 16
Reverse for 'vote' with arguments '('',)' not found. 1 pattern(s) tried: ['polls/(?P<pk>[0-9]+)/vote/$']
Request Method: GET
Request URL: http://127.0.0.1:8000/polls/1/
Django Version: 3.1.6
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'vote' with arguments '('',)' not found. 1 pattern(s) tried: ['polls/(?P<pk>[0-9]+)/vote/$']
Exception Location: /home/dglenn/Projects/Django/innotest/venv/lib/python3.8/site-packages/django/urls/resolvers.py, line 685, in _reverse_with_prefix
Python Executable: /home/dglenn/Projects/Django/innotest/venv/bin/python
Python Version: 3.8.5
Python Path:
['/home/dglenn/Projects/Django/innotest',
'/home/dglenn/Projects/Django/innotest',
'/home/dglenn/Projects/Django/innotest/polls',
'/home/dglenn/bin/pycharm/plugins/python/helpers/pycharm_display',
'/usr/lib/python38.zip',
'/usr/lib/python3.8',
'/usr/lib/python3.8/lib-dynload',
'/home/dglenn/Projects/Django/innotest/venv/lib/python3.8/site-packages',
'/home/dglenn/bin/pycharm/plugins/python/helpers/pycharm_matplotlib_backend']
detail.html as seen from the error message
6 </head>
7 <body>
8 <h1>{{ question.question_text }}</h1>
9
10 {% if error_message %}
11 <p><strong>
12 {{ error_message }}
13 </strong></p>
14 {% endif %}
15
16 <form action="{% url 'polls:vote' question_id %}" method="post">
17 {% csrf_token %}
18
19 {% for choice in question.choice_set.all %}
20
21 <input type="radio" name="choice" id=
22 "choice{{ forloop.counter }}" value="{{ choice.id }}">
23 <label for="choice{{ forloop.counter }}">
24 {{ choice.choice_text }}</label>
25 <br>
Complete detail.html code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Detail</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<p><strong>
{{ error_message }}
</strong></p>
{% endif %}
<form action="{% url 'polls:vote' question_id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id=
"choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">
{{ choice.choice_text }}</label>
<br>
{% endfor %}
<input type="submit" value="Vote">
</form>
</body>
</html>
views.py
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from . models import Choice, Question
# Create your views here.
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
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]:
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,)))
urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path("", views.IndexView.as_view(), name="index"),
path("<int:pk>/", views.DetailView.as_view(), name="detail"),
path("<int:pk>/results/", views.ResultsView.as_view(), name="results"),
path("<int:pk>/vote/", views.vote, name="vote"),
]
Digging down into the local variables active while the exception was raised in the resolvers.py on line 685 unfortunately wasn’t very helpful to me. But I’m sure the forum gurus may have seen this before.
_prefix
'/'
arg_msg
"arguments '('',)'"
args
('',)
candidate_pat
'/polls/%(pk)s/vote/'
candidate_subs
{'pk': ''}
converters
{'pk': <django.urls.converters.IntConverter object at 0x7fe598b56820>}
defaults
{}
k
'pk'
kwargs
{}
lookup_view
'vote'
lookup_view_s
'vote'
m
None
match
True
msg
("Reverse for 'vote' with arguments '('',)' not found. 1 pattern(s) tried: "
"['polls/(?P<pk>[0-9]+)/vote/$']")
n
None
params
['pk']
pattern
'polls/(?P<pk>[0-9]+)/vote/$'
patterns
['polls/(?P<pk>[0-9]+)/vote/$']
possibilities
[([('polls/%(pk)s/vote/', ['pk'])],
'polls/(?P<pk>[0-9]+)/vote/$',
{},
{'pk': <django.urls.converters.IntConverter object at 0x7fe598b56820>})]
possibility
[('polls/%(pk)s/vote/', ['pk'])]
result
'polls/%(pk)s/vote/'
self
<URLResolver <URLResolver list> (None:None) '^/'>
text_candidate_subs
{'pk': ''}
v
''