Reputation: 77
i'm working on a Django app where I am trying to submit a form and a formset in one go.
Getting the formset to render works flawlessly, but submitting it with a POST generates an error... Once i comment out generating the formset from POST data, all works fine, and the form submits without errors
The thing is, the error I get is not very descriptive:
MultiValueDictKeyError at /questions/question/add
'0'
these are my view methods:
def get(self, request, question_id=-1):
initial_data = {
'categories': 1,
'subcategories': 2,
'questionEditor': "Test initial",
'isOpenQuestion': True,
'isMultiChoice': False,
}
category = request.session['category'] if 'category' in request.session else 0
initial_data['categories'] = category
formset_initial_data = list()
if question_id > 0:
question = Question.objects.get(id=question_id)
initial_data = {
'categories': question.subcategories.category.id,
'subcategories': question.subcategories.id,
'questionEditor': question.description,
'isOpenQuestion': question.isOpenQuestion,
'isMultiChoice': question.isMultiChoice,
}
for index, answer in enumerate(question.answer_set.all()):
print answer.description
formset_initial_data.append({
'formulaAnswerEditor': answer.description,
'answerInputBox': answer.isCorrect,
})
question_edit_formset = formset_factory(forms.QuestionEditAnswerForm, extra=(3 if len(formset_initial_data) == 0 else 0))
formset = question_edit_formset(initial=formset_initial_data)
form = forms.QuestionEditForm(data=initial_data)
data = {
'form': form,
'formset': formset,
}
return render(request, "questionEdit.html", dictionary=data)
def post(self, request, question_id=-1):
print request.POST
form = forms.QuestionEditForm(data=request.POST)
question_answers_formset = formset_factory(forms.QuestionEditAnswerForm, extra=0)
formset = question_answers_formset(initial=request.POST)
print form, formset
the form class
class QuestionEditAnswerForm(forms.Form):
id = forms.IntegerField(widget=forms.HiddenInput())
answerInputBox = forms.BooleanField(required=False, widget=forms.CheckboxInput(attrs={
'class': 'answer-input-type',
'type': 'radio',
}))
formulaAnswerEditor = forms.CharField(widget=forms.Textarea(attrs={
'class': "answer-text-area-style answer-cke-remove-bottom-toolbar cke-placeholder"}))
template:
{{ formset.management_form }}
{% for single_answer in formset %}
{{ single_answer.id }}
<div class="margin-answer">
<div class="input-group">
<span class="input-group-addon">
{{ single_answer.answerInputBox }}
</span>
{{ single_answer.formulaAnswerEditor }}
</div>
</div>
{% endfor %}
new forms to the formset are added using JS, but even if I don't add any new form, the error persists...
I have tried following answers to similar questions, but so far with no luck
If anyone knows how to figure this out, I'd be grateful :)
EDIT: full traceback (i'm relatively new to Django and Python, so that doesn't say too much to me :))
Request Method: POST
Request URL: http://localhost:8000/questions/question/add
Django Version: 1.9.6
Python Version: 2.7.11
Installed Applications:
['suit',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'MainPage',
'News',
'Registration',
'StaticSites',
'UserDetails',
'Questions',
'Competitions']
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']
Traceback:
File "/path/to/env/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/path/to/env/env/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/path/to/env/env/lib/python2.7/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/path/to/env/env/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/path/to/env/ekonkurs/Questions/views.py" in post
221. print form, formset
File "/path/to/env/env/lib/python2.7/site-packages/django/utils/six.py" in <lambda>
842. klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
File "/path/to/env/env/lib/python2.7/site-packages/django/utils/html.py" in <lambda>
381. klass.__unicode__ = lambda self: mark_safe(klass_unicode(self))
File "/path/to/env/env/lib/python2.7/site-packages/django/forms/formsets.py" in __str__
70. return self.as_table()
File "/path/to/env/env/lib/python2.7/site-packages/django/forms/formsets.py" in as_table
413. forms = ' '.join(form.as_table() for form in self)
File "/path/to/env/env/lib/python2.7/site-packages/django/forms/formsets.py" in __iter__
74. return iter(self.forms)
File "/path/to/env/env/lib/python2.7/site-packages/django/utils/functional.py" in __get__
33. res = instance.__dict__[self.name] = self.func(instance)
File "/path/to/env/env/lib/python2.7/site-packages/django/forms/formsets.py" in forms
144. for i in range(self.total_form_count())]
File "/path/to/env/env/lib/python2.7/site-packages/django/forms/formsets.py" in _construct_form
170. defaults['initial'] = self.initial[i]
File "/path/to/env/env/lib/python2.7/site-packages/django/utils/datastructures.py" in __getitem__
85. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /questions/question/add
Exception Value: '0'
Upvotes: 1
Views: 1137
Reputation: 599778
The problem is in your post
method: you're passing the data to the formset as the initial
parameter, rather than data
as you do with the form.
(Note that you seem to be making the opposite mistake in the get
method; you're passing initial data to the form as data
, rather than initial
.)
Upvotes: 1