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:

enter image description here

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>

      

0


source to share


1 answer


I think you need to call is_valid

before saving the formset, even if you are 100% sure the forms are valid:



if modelformset.is_valid():
    modelformset.save()

      

0


source







All Articles