with tutorial formmodel form dynamically creating python html django forms django-forms

python - tutorial - Django formset plantea KeyError `form-0-id`



forms meta django (1)

Intento guardar un formset pero sigo recibiendo

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 plantea el mismo error.

Aquí hay una pregunta que parece muy cercana, pero agregar {{form.id}} justo antes del {%for field in form.visible_fields %} no parece ayudar.

Hay un campo de id autogenerado en la tabla de la base de datos, pero no se especifica explícitamente en el modelo (no estoy seguro si eso es relevante). id no aparece en ninguno de los códigos o campos, ni en el código del modelo. id es solo una columna de base de datos generada automáticamente por migrate .

Aquí está la vista que publico en:

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

Aquí está la plantilla que hace la publicación:

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

entonces cada fila es una forma y cada columna un campo:

rastrear:

[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 proviene de esto que agregué en respuesta a una respuesta propuesta a continuación.

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

Ver fuente en Chrome (nombres de campo anónimos, ninguno de ellos es 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>


Creo que debe llamar a is_valid antes de guardar el formset, incluso si está 100% seguro de que los formularios son válidos:

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