0

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?

Community
  • 1
  • 1
Noble-Surfer
  • 3,052
  • 11
  • 73
  • 118
  • Remove your exception handling - this is confusing everything as you are getting two separate exceptions: django has a very nice way of handling exceptions and showing you where the problem really is. – ger.s.brett Feb 15 '17 at 15:56
  • You haven't shown the code for how you create the formsets for `GET` requests. Make sure you use the same prefixes there. – Alasdair Feb 15 '17 at 16:30

0 Answers0