I have a Django website, and on one of the pages, I am trying to upload some images using a form.
When I click the 'Browse' button to select the file I want to upload, a dialog box opens, and I browse to the file and click OK. The name of the selected file is then displayed next to the 'Browse' button.
However, when I then click the 'Submit' button to Submit the form (and upload the attached image to the database entry for this object), the console displays the following output:
Exception thrown in try in if drawing_formset:
u'drawings-0-id' (<class 'django.utils.datastructures.MultiValueDictKeyError'>)
Exception thrown in try in if budget_formset:
ManagementForm data is missing or has been tampered with (<class 'django.core.exceptions.ValidationError'>)
This exception is being handled by the view
that I'm using to attach the images to the form:
def upload_budget_pdfs(request, project_id):
project = Project.objects.get(id=project_id)
print("Value of project in 'upload_budget_pdfs()': ", project)
if request.method == 'POST':
presentations = project.budget_versions.select_related('meeting').prefetch_related('budget_items', 'cci_items', 'presenters').filter(version_number__isnull=False).annotate(vn=F('version_number') * -1).order_by('presentation_date', 'created', '-vn')
print("Value of presentations in 'upload_budget_pdfs()': ", presentations)
drawing_formset = DrawingUploadFormset(request.POST, request.FILES, prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))
if drawing_formset:
print "Before", [b.id for b in project.budget_versions.all()]
# Surround for loop with a try-catch to see what's going on...
try:
for drawing_form in drawing_formset: #ERF(24/01/2017 @ 1610) This line is what's causing the MultiValueDictKeyError
print 'drawing for loop entered in upload_budget_pdfs() - line 1034 '
if drawing_form.instance.budget:
print 'if statement entered - line 1036 '
print 'Instance: ', drawing_form.instance.budget
drawing = drawing_form.save(commit=False)
drawing.budget = drawing_form.instance.budget
drawing.save()
print "drawing.save() called in upload_budget_pdfs() - line 1055 "
print drawing, [b.id for b in project.budget_versions.all()]
except Exception as e:
print 'Exception thrown in try in if drawing_formset: '
print '%s (%s)' % (e.message, type(e))
else:
print("Drawing formset not valid. ", drawing_formset.errors)
budget_formset = DrawingUploadFormset(request.POST, request.FILES, prefix="Drawings")
budget_pdf_formset = BudgetPresentationFormset(request.POST, request.FILES, instance=project, prefix="budgetPDF")
if budget_formset:
try:
budgetSaved = False
for budget_form in budget_formset:
if budget_form:
if budgetSaved == False:
print 'if statement entered - line 1081 '
budget = budget_form.save(commit=False)
budget.save()
print "budget.save() called in upload_budget_pdfs() - line 1097 "
budgetSaved = True
except Exception as e:
print 'Exception thrown in try in if budget_formset: '
print '%s (%s)' % (e.message, type(e))
else:
print("Budget formset not valid. ", budget_formset.errors)
return HttpResponseRedirect(reverse('projects:concept', args=[project_id]))
Having had a look into what might cause this exception to be raised, I came across the answer at: ManagementForm data is missing or has been tampered with, which seems to indicate that I need to be using
{{ my_formset.management_form }}
in my template...
However, I am already using the management_form
in my template:
{% with drawing_form=drawing_formset|getval:forloop.counter0 %}
{# budget_pdf_form=budget_pdf_formset|getval:forloop.counter0 #}
<tr>
{% if not forloop.last %}
<td colspan="3"><label>Drawings</label></td>
{% endif %}
{% for d_field in drawing_form.visible_fields %}
{% if drawing_form.instance.pdf %}
<td colspan="3" class="center">
<a class="button file-download pdf" href="{% url 'costing:pdf_open' presentation_form.instance.id %}?pdf=drawings" target="_blank"></a><a class="pdf-clear" data-view-url="{% url 'costing:pdf_clear' presentation_form.instance.id %}?pdf=drawings"><img class="icon m-l-sm m-b-md" src="{% static "img/bin.png" %}"></a>
<!-- Need a hidden field to actually hold the file that's uploaded to the form -->
<input type="hidden" name = "conceptDrawing" value="{{d_field.title}}">
</td>
{% else %}
<td colspan="3">{{d_field}}</td>
{% for d_hidden in drawing_form.hidden_fields %}
<!--td class="hidden">{{d_hidden}}</td-->
<td class="hidden">
{{budget_formset.as_table}}
{{budget_formset.management_form}}
</td>
{% endfor %}
{% endif %}
{% endfor %}
<tr>
<td colspan="1" class="p-t-md"></td>
<td colspan="4" class="p-t-md"><input type="submit" value="upload"></td>
<td colspan="1" class="p-t-md"></td>
</tr>
</tr>
{% endwith %}
{# Add a similar with statement for budgetPDF form #}
{% with budget_pdf_form=budget_pdf_formset|getval:forloop.counter0 %}
<tr>
{% if not forloop.last %}
<td colspan="3"><label>Budget PDF package</label></td>
{% endif %}
</tr>
<tr>
{% for p_field in budget_pdf_form.visible_fields %}
{% if budget_pdf_form.instance.pdf %}
<td colspan="3" class="center">
<a class="button file-download pdf" href="{% url 'costing:pdf_open' presentation_form.instance.id %}?pdf=budgetPDF" target="_blank"></a><a class="pdf-clear" data-view-url="{% url 'costing:pdf_clear' presentation_form.instance.id %}?pdf=budgetPDF"><img class="icon m-l-sm m-b-md" src="{% static "img/bin.png" %}"></a>
<input type="hidden" name = "conceptBudgetPDF" value="{{p_field.title}}">
<!--a class="button file-download pdf" href="{% url 'costing:pdf_open' presentation_form.instance.id %}?pdf=drawings" target="_blank"></a><a class="pdf-clear" data-view-url="{% url 'costing:pdf_clear' presentation_form.instance.id %}?pdf=drawings"><img class="icon m-l-sm m-b-md" src="{% static "img/bin.png" %}"></a-->
<!-- Need a hidden field to actually hold the file that's uploaded to the form -->
<!--input type="hidden" name = "conceptBudgetPDF" value="{{p_field.title}}"-->
</td>
<td>Some text here</td>
{% else %}
<td colspan="3">{{p_field}}</td>
{%for p_hidden in budget_pdf_form.hidden_fields %}
<td class="hidden">{{p_hidden}}</td>
{{budget_pdf_formset.as_table}}
{{budget_pdf_formset.management_form}}
</td>
{% endfor %}
<td>Other text here</td>
{% endif %}
{% endfor %}
<tr>
<td colspan="1" class="p-t-md"></td>
<td colspan="4" class="p-t-md"><input type="submit" value="upload"></td>
<td colspan="1" class="p-t-md"></td>
</tr>
</tr>
{% endwith %}
I don't understand why I'm getting these exceptions... The MultiValueDictKeyError
would seem to indicate that I am returning/ using several objects where it should just be one, and my guess is that this is happening when I'm assigning the value of drawing_formset
, i.e. it's being given the value of a queryset
, so that will be more than one object.
However, the output that is being displayed in my console would indicate that this exception is only thrown when I try to iterate through the list of objects that have been assigned to the variable drawing_formset
, i.e. in the try
block in the view
, so surely this indicates that I am expecting to have several objects assigned to the variable drawing_formset
, and that I want to iterate through them...?
How can I resolve these exceptions?