Writing Your First Django App, Part 4 - Traceback error after adding results.html

I’m on part 4 of the tutorial and have just added the results.html, and now when I try to access /polls/1/ I get this error:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/polls/1/

Django Version: 5.0.7
Python Version: 3.12.4
Installed Applications:
['polls.apps.PollsConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Python312\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Nonconflictingname\mysite\polls\views.py", line 15, in detail
    return render(request, "polls/detail.html", {"question": question})
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\shortcuts.py", line 25, in render
    content = loader.render_to_string(template_name, context, request, using=using)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loader.py", line 61, in render_to_string
    template = get_template(template_name, using=using)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loader.py", line 15, in get_template
    return engine.get_template(template_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\backends\django.py", line 33, in get_template
    return Template(self.engine.get_template(template_name), self)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\engine.py", line 177, in get_template
    template, origin = self.find_template(template_name)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\engine.py", line 159, in find_template
    template = loader.get_template(name, skip=skip)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loaders\cached.py", line 57, in get_template
    template = super().get_template(template_name, skip)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loaders\base.py", line 23, in get_template
    contents = self.get_contents(origin)
               ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loaders\cached.py", line 26, in get_contents
    return origin.loader.get_contents(origin)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\template\loaders\filesystem.py", line 23, in get_contents
    return fp.read()
           ^^^^^^^^^
  File "<frozen codecs>", line 322, in decode
    <source code not available>
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: UnicodeDecodeError at /polls/1/
Exception Value: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Here is my views.py:

from django.db.models import F
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.urls import reverse
from .models import Choice, Question


def index(request):
    latest_question_list = Question.objects.order_by("-pub_date")[:5]
    context = { "latest_question_list": latest_question_list}
    return render(request, "polls/index.html", context)

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, "polls/detail.html", {"question": question})
    
               
    
def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, "polls/results.html", {"question": question})
    
def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
         selected_choice = questionchoice_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 = F("votes") + 1
         selected_choice.save()
         return HttpResponseRedirect(reverse("polls:results", args=
(question.id,)))

Here is the results.html:

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{
choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>"

Here is the mysite/urls.py:

"""
URL configuration for mysite project.

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/5.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("polls/", include("polls.urls")),
    path("admin/", admin.site.urls),
]

Here is the polls/urls.py:

from django.urls import path

from . import views

app_name = "polls"
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"),
]

This appears to be the key section of the traceback.

I believe we need to see the detail.html and not the results.html template.

detail.html

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

<form action="{% url 'polls:vote' question.id %}" method="post">
    {% csrf_token %}
    <fieldset>
        <legend><h1>{{ question.question_text }}</h1></legend>
        {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
        {% 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 %}
    </fieldset>
    <input type="submit" value="Vote">
    </form>

I see where it appears that you’re doing this on Windows, using Python 3.12 and Django 5.

What are you using as an IDE / Editor for your template files?

Using VS Code. Would you recommend using something else?

Nope, that’s a perfectly fine choice. I really just wanted to find out if you were using something like notepad or if you were trying to use something like Adobe Dreamweaver, each of which having their own particular issues in situations like this.

In your settings (ctrl - ,), under Text Editor / Files, there’s a setting for “Encoding”. What is that setting?

Encoding in VS Code is set to UTF-8.

I’m pretty sure that this error is an indication that the file is actually utf-16. (Or was edited with something that added the byte-order-mark at the beginning of the file.)

Open up that file in VS Code, and look at the bottom of the VS Code window for the “UTF-” indicator. If it says anything other than “UTF-8”, click on it then select “Save with encoding”, and select “UTF-8” from the dropdown.

Wow, that fixed it. I think the issue was caused by me originally creating the file in the terminal using the echo command. While I later opened it in VS Code, the file was originally created using the terminal.

However, now that polls/1 is working, I have noticed that there are no options for me to vote. The “What’s new?” headers load, and so does the Vote button. But there are no poll options.

Can you verify that you have options for Question id = 1?

How would I check/verify this?

Back in Part 2 of the tutorial, in the section Playing with the API, the tutorial shows how you use the manage.py shell command to interact with the database.

You can run this query from within the shell:
Choice.objects.filter(question_id=1)

Note: If you have not done all the steps in that part of the tutorial, you should go back and do them. It’s in that section where those choices are entered.

Choice.objects.filter(question_id=1)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'Choice' is not defined

Please post the complete contents of your models.py file.

import datetime

from django.db import models
from django.utils import timezone

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")
    def __str__(self):
        return self.question_text
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text
    ```

Did you import the Choice model when you were in the shell?

Pretty sure I did before, but just did so again. Now, I get this:

Choice.objects.filter(question_id=1)
<QuerySet []>

So this means you do not have any choices defined for that question. This typically indicates that you skipped one or more steps in part two. Or, you did do those steps, but the PK for the question is not 1.

I definitely remember putting them in, but I must have accidentally removed them during another step. I redefined the choices and now the polls page loads with 2 choices, but trying to vote on either of them gives the following traceback error:

# NameError at /polls/1/vote/

name 'questionchoice_set' is not defined

|Request Method:|POST|
| --- | --- |
|Request URL:|http://127.0.0.1:8000/polls/1/vote/|
|Django Version:|5.0.7|
|Exception Type:|NameError|
|Exception Value:|name 'questionchoice_set' is not defined|
|Exception Location:|C:\Python312\Nonconflictingname\mysite\polls\views.py, line 26, in vote|
|Raised during:|polls.views.vote|
|Python Executable:|C:\Python312\python.exe|
|Python Version:|3.12.4|
|Python Path:|['C:\\Python312\\Nonconflictingname\\mysite', 'C:\\Python312\\python312.zip', 'C:\\Python312\\DLLs', 'C:\\Python312\\Lib', 'C:\\Python312', 'C:\\Python312\\Lib\\site-packages']|
|Server time:|Sun, 25 Aug 2024 07:13:30 +0000|

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/polls/1/vote/

Django Version: 5.0.7
Python Version: 3.12.4
Installed Applications:
['polls.apps.PollsConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Python312\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python312\Nonconflictingname\mysite\polls\views.py", line 26, in vote
    selected_choice = questionchoice_set.get(pk=request.POST["choice"])
                      ^^^^^^^^^^^^^^^^^^

Exception Type: NameError at /polls/1/vote/
Exception Value: name 'questionchoice_set' is not defined