2017-09-03 35 views
0

我試圖挽救一個formset,但我不斷收到Django的表單集引發KeyError異常`形式-0-id`

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引發同樣的錯誤。

Here's a question這似乎很接近,但在{%for field in form.visible_fields %}之前加上{{form.id}}似乎沒有幫助。

有數據庫表自動生成的id場,但不是在模型中(不知道這是有關)明確指定。 id沒有出現在任何形式的代碼或字段或模型代碼。 id是僅由migrate自動生成的數據庫列。

下面是我張貼的觀點:

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 = { 
      ... 
     } 

下面是確實張貼模板:

<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> 

所以每一行是一個形式,每一列的字段:

enter image description here

回溯:

[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來源於此我在響應加到低於建議的回答。在Chrome

print('testing validity') 
if modelformset.is_valid(): 
    print('saving') 
    modelformset.save() 

查看源代碼(匿名字段名,他們都不是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

關鍵錯誤是因爲您錯過了{{form.id}}'。如果你認爲這沒有幫助,你應該顯示你的嘗試。 – Alasdair

+0

@Alasdair編輯補充'{{form.id}}'這給了同樣的錯誤 – Hatshepsut

+0

完整回溯添加到你的問題。 – Alasdair

回答

0

我認爲你必須保存表單集之前調用is_valid,即使你確信100%表格有效:

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

'modelformset.is_valid()'增加'list_ = super(MultiValueDict,self).__ getitem __(key)KeyError:'form-0-id'' – Hatshepsut