Django formset raises KeyError `form-0-id`
I am trying to save a set of forms but I keep getting
list_ = super(MultiValueDict, self).__getitem__(key)
KeyError: 'form-0-id'
During handling of the above exception, another exception occurred:
...
django.utils.datastructures.MultiValueDictKeyError: "'form-0-id'"
modelformset.forms
causes the same error.
Here's a question that seems very close, but adding {{form.id}}
right before {%for field in form.visible_fields %}
doesn't help.
There is an autogenerated field in the database table id
, but not explicitly specified in the model (not sure if this is relevant). id
does not appear in any of the form or field codes or model code. id
is just an autogenerated database column migrate
.
Here is the view I am sending to:
views.py
def list_page(request, list_id):
image_path = get_image_path(list_id)
ordered_men = OrderedTable.objects.filter(list_id=list_id)
ordered_men = list(enumerate(
sorted(ordered_men, key=str)
))
print(f'there are {len(ordered_men)} men')
OrderedManInputFormSet = modelformset_factory(
OrderedManInput,
fields=fields,
form=OrderedManInputForm, extra=0)
ordered_man_input_formset = OrderedManInputFormSet(
form_kwargs={
'choices': ordered_men,
}
)
return render(
request, 'collector/list.html',
{
'list_id': list_id,
'image_path': image_path,
'formset': ordered_man_input_formset,
}
)
def submit(request, list_id):
OrderedManInputFormSet = modelformset_factory(
OrderedManInput,
form=OrderedManInputForm,
fields=fields,
extra=0,
)
modelformset = OrderedManInputFormSet(request.POST)
print('testing validity')
if modelformset.is_valid():
print('saving')
modelformset.save()
return HttpResponseRedirect(
reverse('collector:thanks')
)
def thanks(request):
return render(request, 'collector/thanks.html')
forms.py
class OrderedManInputForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(OrderedManInputForm, self).__init__(args, kwargs)
if 'choices'in kwargs:
# This works
self.fields['full_name'] = forms.ChoiceField(
choices=[('', ' ')] + kwargs['choices'],
required=False
)
class Meta:
model = OrderedManInput
widgets = {}
text_fields = [
...
]
boolean_fields = [
...
]
widgets.update({
field: forms.TextInput()
for field in text_fields
})
widgets.update({
field: forms.CheckboxInput()
for field in boolean_fields
})
fields = text_fields + boolean_fields
labels = {
...
}
Here's the template that does the wiring:
<form action="{% url 'collector:submit' list_id %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ formset.management_form }}
<table id="id_data_table">
{% for form in formset %}
{{form.id}}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr></thead>
{% endif %}
<tr>
{%for field in form.visible_fields %}
<td>
{{field}}
</td>
{%endfor%}
</tr>
{% endfor %}
</table>
<p/>
<div class="div-submit">
<input type="submit"/>
</div>
</form>
so each row is a form and each column is a field:
tracker:
[03/Sep/2017 00:08:21] "GET /collector/183618 HTTP/1.1" 200 20455
[03/Sep/2017 00:08:21] "GET /static/style.css HTTP/1.1" 200 1123
[03/Sep/2017 00:08:21] "GET /static/admin/js/vendor/jquery/jquery.js HTTP/1.1" 200 258648
[03/Sep/2017 00:08:21] "GET /static/lists_of_men_cropped/41550_1821100522_1170-01047.jpg HTTP/1.1" 404 1769
[03/Sep/2017 00:08:21] "GET /static/lists_of_men_cropped/41550_1821100522_1170-01047.jpg HTTP/1.1" 404 1769
Not Found: /favicon.ico
[03/Sep/2017 00:08:21] "GET /favicon.ico HTTP/1.1" 404 2078
testing validity
Internal Server Error: /collector/183618/submit/
Traceback (most recent call last):
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/utils/datastructures.py", line 83, in __getitem__
list_ = super(MultiValueDict, self).__getitem__(key)
KeyError: 'form-0-id'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/user/Documents/site/crowdsource/collector/views.py", line 87, in submit
if modelformset.is_valid():
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/formsets.py", line 321, in is_valid
self.errors
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/formsets.py", line 295, in errors
self.full_clean()
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/formsets.py", line 344, in full_clean
form = self.forms[i]
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/utils/functional.py", line 35, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/formsets.py", line 144, in forms
for i in range(self.total_form_count())]
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/formsets.py", line 144, in <listcomp>
for i in range(self.total_form_count())]
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/forms/models.py", line 603, in _construct_form
pk = self.data[pk_key]
File "/home/user/Documents/site/venv/lib/python3.6/site-packages/django/utils/datastructures.py", line 85, in __getitem__
raise MultiValueDictKeyError(repr(key))
django.utils.datastructures.MultiValueDictKeyError: "'form-0-id'"
[03/Sep/2017 00:09:02] "POST /collector/183618/submit/ HTTP/1.1" 500 112006
testing validity
follows from this, which I added in response to the suggested answer below.
print('testing validity')
if modelformset.is_valid():
print('saving')
modelformset.save()
View source in Chrome (Anonymous field names, none of which are id
):
<html>
<link rel="stylesheet" type="text/css" href="/static/style.css" />
<script type="text/javascript" src="/static/admin/js/vendor/jquery/jquery.js"></script>
<body>
<div class="top">
<div class="div-img sub">
<img id="clip" src="/static/lists_of_men_cropped/41550_1821100522_1170-01047.jpg"/>
</div>
<div class="div-table sub">
<form action="/collector/183618/submit/" method="POST" enctype="multipart/form-data">
<input type='hidden' name='csrfmiddlewaretoken' value='GGVRrXaNH46axDImq2DEjEtV4mAaIiVLMpK6fpgyLXpLeVrIVOGICZ0SIMGtxeDV' />
<input type="hidden" name="form-TOTAL_FORMS" value="10" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="10" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
<table id="id_data_table">
<input type="hidden" name="id" id="id_id" />
<thead><tr>
<th>field 1</th>
<th>field 2</th>
<th>field 3</th>
<th>field 4</th>
<th>field 5</th>
<th>field 6</th>
<th>field 7</th>
<th>field 8</th>
<th>field 9</th>
</tr></thead>
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
<input type="hidden" name="id" id="id_id" />
<tr>
<td>
<input type="text" name="field_1" id="id_field_1" />
</td>
<td>
<input type="text" name="field_2" id="id_field_2" />
</td>
<td>
<select name="field_3" id="id_field_3">
<option value="" selected> </option>
<option value="0">option a</option>
<option value="1">option b</option>
<option value="2">option c</option>
<option value="3">option d</option>
<option value="4">option e</option>
<option value="5">option f</option>
<option value="6">option g</option>
<option value="7">option h</option>
<option value="8">option i</option>
<option value="9">option j</option>
</select>
</td>
<td>
<input type="text" name="field_4" id="id_field_4" />
</td>
<td>
<input type="text" name="field_5" id="id_field_5" />
</td>
<td>
<input type="text" name="field_6" id="id_field_6" />
</td>
<td>
<input type="text" name="field_7" id="id_field_7" />
</td>
<td>
<input type="checkbox" name="field_8" id="id_field_8" />
</td>
<td>
<input type="checkbox" name="field_9" id="id_field_9" />
</td>
</tr>
</table>
<p/>
<div class="div-submit">
<input type="submit"/>
</div>
</form>
</div>
</div>
</body>
<script>
function copyTextValue(bf) {
var text = document.getElementsByClassName("call-number")[0].value ;
elements = document.getElementsByClassName("call-number");
for (var i = 0; i < elements.length; i++){
elements[i].value = text
}
}
</script>
</html>
source to share