@sunnyfox

Почему возникает MultiValueDictKeyError при голосовании в polls plugin для Django CMS?

Изучаю Django CMS, пыталась создать плагин polls для Django CMS 3.2.0 на основе стандартного приложения django-polls. Следовала инструкциям в официальных доках. Весь код скопирован оттуда. Но после размещения плагина на главной странице моего проекта я вижу только сам вопрос и радио-баттоны по числу ответов, но не вижу текста ответов. После выбора одного из ответов и нажатия кнопки Vote получаю страницу с ошибкой. Вот трейсбек:


Environment:

Request Method: POST
Request URL: localhost:8000/ru/polls/2/vote

Django Version: 1.8.7
Python Version: 2.7.10
Installed Applications:
('djangocms_admin_style',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'django.contrib.sites',
'django.contrib.sitemaps',
'django.contrib.staticfiles',
'django.contrib.messages',
'debug_toolbar',
'cms',
'menus',
'sekizai',
'treebeard',
'djangocms_text_ckeditor',
'djangocms_style',
'djangocms_column',
'filer',
'easy_thumbnails',
'cmsplugin_filer_image',
'cmsplugin_filer_file',
'cmsplugin_filer_folder',
'cmsplugin_filer_teaser',
'cmsplugin_filer_utils',
'cmsplugin_filer_video',
'djangocms_googlemap',
'djangocms_inherit',
'djangocms_link',
'reversion',
'fatdiet',
'polls',
'polls_plugin')
Installed Middleware:
('cms.middleware.utils.ApphookReloadMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'cms.middleware.language.LanguageCookieMiddleware')

Traceback:
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\django\views\generic\base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\polls\views.py" in post
26. choice = Choice.objects.get(id=request.POST['choice_pk'])
File "C:\Users\Fox\Envs\fatdiet\lib\site-packages\django\utils\datastructures.py" in __getitem__
322. raise MultiValueDictKeyError(repr(key))

Exception Type: MultiValueDictKeyError at /ru/polls/2/vote/
Exception Value: "'choice_pk'"


Вот код из \site-packages\polls\views.py откуда поднимается ошибка:

from django.views.generic import DetailView, ListView, RedirectView
from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _

from polls.models import Choice, Poll, Vote


class PollListView(ListView):
    model = Poll


class PollDetailView(DetailView):
    model = Poll

    def get_context_data(self, **kwargs):
        context = super(PollDetailView, self).get_context_data(**kwargs)
        context['poll'].votable = self.object.can_vote(self.request.user)
        return context


class PollVoteView(RedirectView):
    def post(self, request, *args, **kwargs):
        poll = Poll.objects.get(id=kwargs['pk'])
        user = request.user
        choice = Choice.objects.get(id=request.POST['choice_pk'])
        Vote.objects.create(poll=poll, user=user, choice=choice)
        messages.success(request, _("Thanks for your vote."))
        return super(PollVoteView, self).post(request, *args, **kwargs)

    def get_redirect_url(self, **kwargs):
        return reverse_lazy('polls:detail', args=[kwargs['pk']])


А вот код из poll_plugin.html (взят из доков as is):

<h1>{{ instance.poll.question }}</h1>

<form action="{% url 'polls:vote' instance.poll.id %}" method="post" name="form">
    {% csrf_token %}
    <div class="form-group">
        {% for choice in instance.poll.choice_set.all %}
            <div class="radio">
                <label>
                    <input type="radio" name="choice" value="{{ choice.id }}">
                    {{ choice.choice_text }}
                </label>
            </div>
        {% endfor %}
    </div>
    <input type="submit" value="Vote" />
</form>


Если написать {{ choice }} вместо {{ choice.choice_text }}, то текст вопросов видно, но при голосовании ошибка остается.
Копаюсь в коде приложения django-polls и в коде своего плагина второй день и никак не могу решить проблему. Что я делаю не так?
  • Вопрос задан
  • 430 просмотров
Пригласить эксперта
Ответы на вопрос 1
@sunnyfox Автор вопроса
Нашла первый шаг решения :)
В атрибутах инпута надо было писать name="choice_pk" и текст выводить как {{choice.choice}}. Видимо, версия polls обновилась-изменилась.

Правда, вылезла вторая ошибка, теперь при голосовании получаю:
IntegrityError at /ru/polls/2/vote/
columns user_id, poll_id are not unique


Буду сейчас расследовать эту проблему.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы