0
votes

I'm stuck at Django's official tutorial (see Writing your first Django app, part 4). https://docs.djangoproject.com/en/3.1/intro/tutorial04/

I get the following error:

https://i.stack.imgur.com/7zPI9.png

In this Django project, inside the poll app I'm making, we're supposed to make a vote() view in views.py which should process the POST request data of the poll and redirect us to the results() view (there's no template for the vote()view, it's just in charge of processing the data we send through the poll). At first I thought I had a typo error, but I then copy-pasted everything directly out of the documentation tutorial (which I linked at the beginning of this question) and the error persisted.

views.py

from django.http import HttpResponse, HttpResponseRedirect
from django.http import Http404
from django.shortcuts import get_object_or_404, render
from django.template import loader
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):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    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 = 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,)))

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'),
]

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>

Index.html

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="{% url 'polls:detail' question.id %}">{{ 
question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

Detail.html

<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>

If this helps anyone

Traceback (most recent call last):
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Danny\Python\Poll\mysite\polls\views.py", line 41, in vote
    selected_choice = question.choice_set.get(pk=request.POST['choice'])
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 418, in get
    clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 942, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 962, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, *args, **kwargs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 969, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 
1358, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 
1377, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 
1319, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 
1165, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\lookups.py", line 76, in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "C:\Users\Danny\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\__init__.py", line 1776, in get_prep_value
    raise e.__class__(
ValueError: Field 'id' expected a number but got '{{ \r\nchoice.id }}'.
2
Could you please re-paste the image? It didn't come through. I'm not seeing in your code where your {{ choice.id }} comes into play, so maybe it's in the image. - Kentaro
Sorry, still new to posting questions here. Thanks for being patient. - Danny
@keepAlive The error is still the same. - Danny
Could you try the next thing: reverse('polls:results',kwargs={'question_id': question.id}) Taken from stackoverflow.com/questions/58107188/… - Ramsés Martínez Ortiz
@RamsésMartínezOrtiz it's still giving me the same error. I may have to wrap this project up. It could be something deeper beyond this project as it states query.py and lookups.py in the exceptions which isn't part of the project creation. - Danny

2 Answers

0
votes

for some reason django is redirecting with the int: question_id as string, could you add your urls file?

0
votes

I got the same error when I learned the tutorial part 4.

Error: Field 'id' expected a number but got '{{ \r\nchoice.id }}'
the error is "\r\n" before the choice.id

In detail.html, there should be no carriage return here.

value="{{ choice.id }}"

Remove the carriage return before choice.id, then refresh the web page. Shouldn't be an error.

<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>