https://static.djangoproject.com/img/logos/django-logo-negative.png

[Python Django] How To solve “ManagementForm data is missing or has been tampered with” issue?

We use forms to either post something or to retrieve items from the database. Simple with the help of form we perform POST and GET requests. In Python’s Django framework we can use forms to perform such operation.https://static.djangoproject.com/img/logos/django-logo-negative.png

When we want to update a single value in a form we can perform it from django normal forms. But when we want to update multiple entries in a form and update them all at once, we cant perform that operation only with the help of Django.forms. In that case we need to import inlineformset_factory.

“ManagementForm data is missing or has been tampered with”

Solution to this error is simple but first let me show you how to use formset from inlineformset_factory such that you will have an idea about the missing thing that caused this error.

from django.forms import inlineformset_factory

def createOrder(request, pk):
    OrderFormSet = inlineformset_factory(Customer, Order, fields=('product', 'status'))
    customer = Customer.objects.get(id=pk)
    formset = OrderFormSet(instance=customer)
    # form = OrderForm(initial={'customer':customer})
    if request.method == 'POST':
        # print('Printing POST:', request.POST)
        # form = OrderForm(request.POST)
        formset = OrderFormSet(request.POST, instance=customer)
        if formset.is_valid():
            formset.save()
            return redirect('/')

    context = {'formset': formset}
    return render(request, 'account/order_form.html', context)

In above code we have imported inlineformset_factory in the first line. So whenever you want to update multiple entries in a form and see those changes

Now inside the method createOrder, you can see I have commented out the form and introduced formset. Since I want to order multiple items at once I am using formset. Then that particular formset is passed as context which renders the request.

Now in your template i.e. order_form.html in my case, you need to reflect the formset in such a way that will display the the entries in your form. The form should also allow you to enter multiple orders and should update the order.

Initally in your template your code was something like below to reflect a form:

<div class="row">
            <form action="" method="POST">
                {% csrf_token %}
                {{form}}
            <input type="submit" name="Submit">
            </form>
</div>

This was correct when you had to work with form where we would update a single entry. But now that your method is formset in order to reflect that you should write your template like this:

<div class="row">
            <form action="" method="POST">
                {% csrf_token %}
                { for form in fromset %}
                 {{form}}
                {% endfor %} 
            <input type="submit" name="Submit">
            </form>
</div>

This is how we include formset. It treats each entries in your form as unique form. Doing this we can update multiple entries at once.

But this is not enough to update your form. This is the exact case when you will see the ManagementForm Error which is the title of our blog. This is because we are missing one method of formset which manages data of our form. Add {{ formset.management_form }} in your code and this error will be solved. You template should finally look somethis like below:

<div class="row">
            <form action="" method="POST">
                {% csrf_token %}
                {{ formset.management_form }}
                    { for form in fromset %}
                         {{form}}
                         <hr>
                    {% endfor %} 
            <input type="submit" name="Submit">
            </form>
</div>