python - formulaire - update form django



Django formset soulève KeyError `form-0-id` (1)

Je pense que vous devez appeler is_valid avant d'enregistrer le formset, même si vous êtes sûr à 100% que les formulaires sont valides:

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

J'essaye de sauver un formset mais je continue à obtenir

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 soulève la même erreur.

Voici une question qui semble très proche, mais ajouter {{form.id}} juste avant {%for field in form.visible_fields %} ne semble pas aider.

Il existe un champ d' id autogénéré dans la table de base de données, mais il n'est pas spécifié explicitement dans le modèle (il n'est pas certain que cela soit pertinent). id n'apparaît dans aucun code ou champ de formulaire ou code de modèle. id est seulement une colonne de base de données générée automatiquement par migrate .

Voici la vue que je poste à:

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

Voici le modèle qui fait l'annonce:

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

donc chaque ligne est un formulaire et chaque colonne un champ:

traceback:

[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 vient de ce que j'ai ajouté en réponse à une réponse proposée ci-dessous.

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

Voir la source dans Chrome (noms de champs anonymes, aucun d'entre eux n'est un 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>




django-forms