Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django issues : Django ManagementForm data is missing or has been tampered with

Tags:

python

django

I have been going through every question ever asked in regards to this issue but can't seem to find the solution.

I am trying to allow a user to submit multiple objects and save to the data base using a formset with 2 foreignkeys.

I can get the Forms to save that data into the database but cannot get the forms in the formset to save because of the ManagementForm error. The issue is not that I don't have it in the HTML. (check the HMTL code below.) I also have a prefix set for the formset.

I don't know if i need to create a custom form and formset instead of using model's. Maybe I need to Validate the information in formsets better.

The error I get is:

/home/aking/signatureProject/signatureApp/views.py in signatures
        if formset.is_valid(): ...
Variable    Value
DD          <DDForm bound=True, valid=True, fields=(downdraft_id)>
PR          <PRForm bound=True, valid=True, fields=(report_id;report_desc)>
SignatureFormSet    <class 'django.forms.formsets.SigFormFormSet'>
formset <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>
request <WSGIRequest: POST '/signatureApp/signatures/'>
views.py

/usr/lib64/python2.7/site-packages/django/forms/formsets.py in is_valid
forms_valid True
self    <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>

/usr/lib64/python2.7/site-packages/django/forms/formsets.py in errors
self.full_clean() 
self <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>

/usr/lib64/python2.7/site-packages/django/forms/formsets.py in full_clean
for i in range(0, self.total_form_count()): 
empty_forms_count  0
self    <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>

/usr/lib64/python2.7/site-packages/django/forms/formsets.py in total_form_count
return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max) 
self    <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>

/usr/lib64/python2.7/site-packages/django/utils/functional.py in __get__
res = instance.__dict__[self.name] = self.func(instance) 
cls <class 'django.forms.formsets.SigFormFormSet'>
instance    <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>
self    <django.utils.functional.cached_property object at 0x1b29dd0>

/usr/lib64/python2.7/site-packages/django/forms/formsets.py in management_form
 code='missing_management_form',
form <ManagementForm bound=True, valid=False, fields=(TOTAL_FORMS;INITIAL_FORMS;MIN_NUM_FORMS;MAX_NUM_FORMS)>
self <django.forms.formsets.SigFormFormSet object at 0x7f44601a4e10>

Views.py

from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from signatureApp.forms import DDForm,PRForm,SigForm
from django.forms.formsets import formset_factory

def signatures(request):
    SignatureFormSet = formset_factory(SigForm)
    if request.method == "POST":
        DD = DDForm(request.POST)
        PR = PRForm(request.POST)
        formset = SignatureFormSet(request.POST, prefix='SFS')
        if DD.is_valid() and PR.is_valid():
            DD.save()
            PR.save(commit=False)
            PR.draft_id = DD.cleaned_data['draft_id']
            PR.save()
            if formset.is_valid():
                for form in formset:
                    form.save(commit=False)
                    form.draft_id = DD.cleaned_data['draft_id']
                    form.report_id = PR.cleaned_data['report_id']
                    sig_type = form.cleaned_data.get('sig_type')
                    sig_desc = form.cleaned_data.get('sig_desc')
                    sig_rule = form.cleaned_data.get('sig_rule')
                    form.save(True)
    return render(request, 'reporting.html', {'DD':DDForm, 'PR':PRForm, 'SignatureFormSet':SignatureFormSet})

HTML

<form class='signatures' method='POST'>
    {% csrf_token %}
    {{ SignatureFormSet.management_form }}
        <div id='draft'>
            <h1>Enter Information from New Report Below</h1>
            <p><strong>ID:</strong><br>{{ DD.draft_id }}</p>
        </div>
        <div id='report'>
            <p><strong>Report Number:</strong><br>{{ PR.report_id }}</p>
            <p><strong>Report Description:</strong><br>{{ PR.report_desc }}</p>
        </div>
        {% for form in SignatureFormSet %}
        <div id='{{form.prefix}}' class='dynamic-form'>
            <p><strong>Signature Type:</strong><br>{{ form.sig_type }}</p>
            <p><strong>Signature Description:</strong><br>{{ form.sig_desc }}</p>
            <p><strong>Signature Rule:</strong><br>{{ form.sig_rule }}</p>
        {% endfor %}
        </div>
        <div class="btn-group">
            <button class="addSignature">Add a signature</button>
            <button id="submit-button">Submit</button>
        </div>
    </form>

forms.py

from django import forms
from signatureApp.models import draft_report, report, signatures

class DDForm(forms.ModelForm):
    class Meta:
        model = draft_report
        fields = ['draft_id',]

class PRForm(forms.ModelForm):
    class Meta:
        model = report
        exclude = ('draft_id',)

class SigForm(forms.ModelForm):
    class Meta:
        model = signatures
        exclude = ('draft_id','report_id',)
like image 952
Andrew King Avatar asked Nov 27 '17 18:11

Andrew King


1 Answers

You need to instantiate all the forms and the formset in the GET branch. And you need to use the prefix when you instantiate the formset there.

def signatures(request):
    SignatureFormSet = formset_factory(SigForm)
    if request.method == "POST":
        ...
    else:
        DD = DDForm()
        PR = PRForm()
        formset = SignatureFormSet(prefix='SFS')
    return render(request, 'reporting.html', {'DD': DD, 'PR': PR, 'SignatureFormSet': formset})
like image 198
Daniel Roseman Avatar answered Oct 13 '22 00:10

Daniel Roseman