0

I'm having problems with the Django tutorial... I'm getting an Incomplete format error from one of my templates, but I'm not finding anything specifically wrong.

Environment:


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

Django Version: 1.9.5
Python Version: 3.5.1
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.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template C:\Users\Monte Milanuk\Desktop\mysite2\templates\polls\detail.html, error at line 7
   incomplete format   1 : <h1>{{ question.question_text }}</h1>
   2 : 
   3 : {% if error_message %}
   4 :     <p><strong>{{ error_message }}</strong></p>
   5 : {% endif %}
   6 : 
   7 : <form action=" {% url 'polls:vote' question.id %} " method="post">
   8 :     {% csrf_token %}
   9 :     {% for choice in question.choice_set.all %}
   10 :         <input type="radio" name="choice" id="choice{{ forloop.counter }}"
   11 :                value="{{ choice.id }}" />
   12 :         <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br/>
   13 :     {% endfor %}
   14 : 
   15 : <input type="submit" value="Vote" />
   16 : </form>
   17 : 

Traceback:

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\core\handlers\base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\Monte Milanuk\Desktop\mysite2\polls\views.py" in detail
  17.     return render(request, 'polls/detail.html', {'question': question})

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\shortcuts.py" in render
  67.             template_name, context, request=request, using=using)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\loader.py" in render_to_string
  97.         return template.render(context, request)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\backends\django.py" in render
  95.             return self.template.render(context)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\base.py" in render
  206.                     return self._render(context)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\base.py" in _render
  197.         return self.nodelist.render(context)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\base.py" in render
  992.                 bit = node.render_annotated(context)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\base.py" in render_annotated
  959.             return self.render(context)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\template\defaulttags.py" in render
  499.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\core\urlresolvers.py" in reverse
  600.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))

File "C:\Users\Monte Milanuk\Anaconda3\envs\django\lib\site-packages\django\core\urlresolvers.py" in _reverse_with_prefix
  488.                 if re.search('^%s%s' % (re.escape(_prefix), pattern), candidate_pat % candidate_subs, re.UNICODE):

Exception Type: ValueError at /polls/1/
Exception Value: incomplete format

polls\urls.py

from django.conf.urls import url

from . import views

app_name = 'polls'
urlpatterns = [
    #  ex: /polls/
    url(r'^$', views.index, name='index'),

    #  ex: /polls/5
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

    #  ex: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),

    #  ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/%$', views.vote, name='vote'),
]

views.py

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse

from .models import Choice, Question


# Create your views here.
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 = 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 prevent data from being posted twice if a user hits
        #  the Back button.
        return HttpResponseRedirect(
            reverse('polls:results', args=(question.id,)))

Is there someplace else in my code I should be looking for the source of this error?

4
  • Please show your url patterns. Commented Apr 11, 2016 at 8:54
  • You should create a minimal reproducible example. Commented Apr 11, 2016 at 8:54
  • @Sayse Really. With the number of files involved with a Django project, how do you see that working? Commented Apr 11, 2016 at 8:56
  • Look at the majority of other questions in the django tag, they all seem to manage to make one Commented Apr 11, 2016 at 8:57

1 Answer 1

5

The % in this url pattern is causing the error. Remove it.

url(r'^(?P<question_id>[0-9]+)/vote/%$', views.vote, name='vote'),
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! If you don't mind me asking, how does a % in the urlpattern for 'vote' affect the view for 'detail'? And why such an obscure error message?
I agree it's a tricky one to debug, because the error page shows the template, but the problem is in the urls.py. Since the problem is with the {% url %} tag and the traceback mentions reverse, it's a good idea to look at urls. In Python % signs are used for string formatting e.g. "my name is %s" % name. The percent sign by itself causes the Incomplete format error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.