ManagementForm data is missing or has been tampered with
Asked Answered
B

4

26

I am trying to create a formset to save records in a go. But, I keep getting the error when I submit my form. And if possible please as tell me how should I save my batch of records.

My views.py:

def weekly_progress(request):
    ProgressFormSet = formset_factory(WeeklyProgressReportForm, extra=16)
    formset = ProgressFormSet(request.POST or None)

    if formset.is_valid():
        for f in formset:
           print(f)

    return render(request, "progress/progressentry.html", {'formset' : formset})

My forms.py

class WeeklyProgressReportForm(forms.ModelForm):
    class Meta:
       model = WeeklyProgressReport
       fields = ('target_date', 'this_date', 'pkgno', 'slno', 'description', 'unit', 'receipt_this_week', 'issue_this_week', 'erection_this_week')
       widgets = {
        'target_date': forms.DateInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
        'this_date': forms.DateInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
        'pkgno': forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
        'slno': forms.NumberInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
        'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 1, 'readonly': 'readonly'}),
        'unit': forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
        'receipt_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01}),
        'issue_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01}),
        'erection_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01, 'readonly': 'readonly'}),
       }

My template:

<form id="contractor-form" method="post" action="">
    {% csrf_token %}

    <!-- First Row -->
    <div class="col-lg-6">
        <div class="panel panel-primary">
            <div class="panel-heading">Select Your Package</div>
            <div class="panel-body">
                <div class="col-lg-4">                        
                    <h4><label class="label label-primary">Package Number</label></h4>
                </div>
                <div class="col-lg-4">
                    <select id="pkgno-select" class="form-control">                                
                        <option value="12 (BRP)">12 (BRP)</option>
                        <option value="13 (BRP)">13 (BRP)</option>
                        <option value="13 (DHB)">13 (DHB)</option>
                        <option value="14 (DHB)">14 (DHB)</option>
                    </select>
                </div>
                <div class="col-lg-4">                        
                        <button type="button" id="date-edit" class="btn btn-warning">Edit Date</button>                        
                </div>
            </div>
        </div>
    </div>


    <!-- Second Row -->
    <div class="col-lg-12">
        <div class="panel panel-primary">
            <div class="panel-heading">Quantities</div>
            <div class="panel-body">
                <table class="table table-hover">
                    <thead>
                        <tr>
                            <th>Target Date</th>
                            <th>This Date</th>
                            <th>Pkg Number</th>
                            <th>Sl Number</th>
                            <th>Description</th>
                            <th>Unit</th>
                            <th>Receipt This Week</th>
                            <th>Issue This Week</th>
                            <th>Erection This Week</th>                                
                        </tr>
                    </thead>
                    <tbody>
                        {% for form in formset %}
                        <tr>
                           <td>{{ form.target_date }}</td>
                           <td>{{ form.this_date }}</td>
                           <td>{{ form.pkgno }}</td>
                           <td>{{ form.slno }}</td>
                           <td>{{ form.description }}</td>
                           <td>{{ form.unit }}</td>
                           <td>{{ form.receipt_this_week }}</td>
                           <td>{{ form.issue_this_week }}</td>
                           <td>{{ form.erection_this_week }}</td>                               
                        </tr>
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!-- Submit Button -->
    <div class="well well-lg">
        <button type="submit" class="btn btn-success btn-lg btn-block">Save</button>
    </div>
</form>

My models.py

class WeeklyProgressReport(models.Model):
   target_date = models.DateField()
   this_date = models.DateField()
   pkgno = models.CharField(max_length=10)
   slno = models.IntegerField(max_length=2)
   description = models.CharField(max_length=50)
   unit = models.CharField(max_length=5)
   target_quantity = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   receipt_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   receipt_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   issue_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   issue_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   erection_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
   erection_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)    

   def __unicode__(self):
       return self.pkgno
Bb answered 15/8, 2014 at 17:50 Comment(0)
U
45

You have to render the management form in your template. The docs explain why and how; some selected quotes:

This form is used by the formset to manage the collection of forms contained in the formset. If you don’t provide this management data, an exception will be raised[.]

The management form is available as an attribute of the formset itself. When rendering a formset in a template, you can include all the management data by rendering {{ my_formset.management_form }} (substituting the name of your formset as appropriate).

Undertow answered 15/8, 2014 at 17:54 Comment(3)
thequickblog.com/…Costumer
when it comes to me, it seems that i have to use {% for form in formset %} {{form}} {%endfor%} to make it work. when I just used some of the field of my model form like {{ form.some_field}} , I kept getting this error.Blasien
I had to add the {{ formset.management_form }} inside the html <form> tags. It didn't work otherwiseKhan
F
12

write {{ formset.management_form }} above your {% for form in formset %}

like this

{{ formset.management_form }}
{% for form in formset %}
Fragmentation answered 2/5, 2020 at 21:12 Comment(0)
L
4

I had the same problem trying to use two formset on same page, I'm adding it's solution coz I didn't find it anywhere else.

Make sure you add the prefix param as

formset = ProgressFormSet(request.POST or None, prefix="fs1")

to GET and POST request both.

Llamas answered 1/1, 2022 at 8:49 Comment(0)
G
0

For those that do have the {{ formset.management_form }} in their template, and do use the correct variable name for the formset, but are still seeing the error message

ManagementForm data is missing or has been tampered with

Make sure not to initialize your formset with empty data

For example, data=None is no problem:

>>> MyFormSet(data=None).non_form_errors()
[]

However, data={} is a problem:

>>> MyFormSet(data={}).non_form_errors()
['ManagementForm data is missing or has been tampered with. Missing fields: ...']

Beware

The latter case also arises if you try to do MyFormSet(data=request.POST) when handling a GET request, because request.POST will then be an empty QueryDict.

If required, a workaround would be e.g. MyFormSet(data=request.POST or None).

Gynaecology answered 24/10, 2023 at 9:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.