Skip to main content
 首页 » 编程设计

python之Django 问题 : Django ManagementForm data is missing or has been tampered with

2025年01月19日41mayingbao

我一直在研究关于这个问题的每一个问题,但似乎找不到解决方案。

我正在尝试允许用户提交多个对象并使用带有 2 个外键的表单集保存到数据库。

我可以获取表单以将该数据保存到数据库中,但由于 ManagementForm 错误而无法获取要保存的表单集中的表单。问题不在于我在 HTML 中没有它。 (检查下面的 HMTL 代码。)我还为表单集设置了前缀。

我不知道是否需要创建自定义表单和表单集而不是使用模型。也许我需要更好地验证表单集中的信息。

我得到的错误是:

/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> 

View .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> 

表单.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',) 

请您参考如下方法:

您需要在 GET 分支中实例化所有表单和表单集。并且在此处实例化表单集时需要使用前缀。

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})