Django Crispy forms-内嵌表单集';管理表单数据&x27;更新视图出错

Django Crispy forms-内嵌表单集';管理表单数据&x27;更新视图出错,django,django-forms,django-crispy-forms,Django,Django Forms,Django Crispy Forms,晚上好, 我在处理表单时遇到了麻烦。我遵循以下指南: 编辑 我认为问题与双提交按钮有关。devicemodel表单有一个按钮,按下该按钮时会产生此错误。但是资源助手中还有一个保存按钮,当提交该按钮时,我会得到一个空的模型表单错误 我添加了操作每个按钮时发生的情况的屏幕截图 当我得到错误时,我肯定错过了什么: ['ManagementForm data is missing or has been tampered with'] 以下是我的更新视图: class EditDeviceMo

晚上好,

我在处理表单时遇到了麻烦。我遵循以下指南:

编辑 我认为问题与双提交按钮有关。devicemodel表单有一个按钮,按下该按钮时会产生此错误。但是资源助手中还有一个保存按钮,当提交该按钮时,我会得到一个空的模型表单错误

我添加了操作每个按钮时发生的情况的屏幕截图

当我得到错误时,我肯定错过了什么:

['ManagementForm data is missing or has been tampered with']
以下是我的更新视图:

class EditDeviceModel(PermissionRequiredMixin, SuccessMessageMixin, UpdateView):
    model = DeviceModel
    form_class = DeviceModelForm

    template_name = "app_settings/base_formset.html"
    permission_required = 'config.change_devicemodel'
    success_message = 'Device  Type "%(model)s" saved successfully'

    def get_success_url(self, **kwargs):         
        return '{}#device_models'.format(reverse("config:config_settings"))

    def get_success_message(self, cleaned_data):
        return self.success_message % dict(
            cleaned_data,
            model=self.object.model,
        )     

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title']='Edit Device Model'
        if self.request.POST:
            context['formset'] = DeviceFormSet(self.request.POST, instance=self.object)
        else:
            context['formset'] = DeviceFormSet(instance=self.object)
        context['helper'] = DeviceFormSetHelper()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']
        if formset.is_valid():
            self.object = form.save()
            formset.instance = self.object
            formset.save()
            return redirect(self.success_url)
        else:
            return self.render_to_response(self.get_context_data(form=form)) 
这是我的表格:

class MonitoredResourceForm(forms.ModelForm):
    class Meta:
        model = MonitoredResource
        fields = ['resource','model']

    def __init__(self, *args, **kwargs):
        self.is_add = kwargs.pop("is_add", False)
        super(MonitoredResourceForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_id = 'snmp_resource_form'
        self.helper.form_method = 'POST'
        self.helper.layout = Layout(
            Div(    
                Div(
                    Field('model'),
                    Field('resource', placeholder="Resource"),
                    css_class='col-lg-3'
                ),
            css_class='row'
            ),
            Div(
                Div(
                    HTML("""<input type="submit" name="submit" value="""),
                    HTML('"Add' if self.is_add else '"Update' ),
                    HTML(""" monitored resource" class="btn btn-primary"/>"""),
                    HTML("""<a href="{% url 'config:config_settings' %}#monitored_resources" class="btn btn-primary">Cancel</a>"""),
                    HTML("""{% if object %}
                            <a href="{% url 'config:delete_monitoredresource' object.id %}"
                            class="btn btn-danger">
                            Delete <i class="fa fa-trash-o" aria-hidden="true"></i></a>
                            {% endif %}"""),
                    css_class='col-lg-12'
                    ),
                css_class='row'
                ),
        ) 

class DeviceModelForm(forms.ModelForm):
    class Meta:
        model = DeviceModel
        fields = ['model','vendor','device_type','ports','uplink_speed']

    def __init__(self, *args, **kwargs):
        self.is_add = kwargs.pop("is_add", False)
        super(DeviceModelForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_id = 'device_type_form'
        self.helper.form_method = 'POST'
        self.helper.layout = Layout(
            Div(    
                Div(
                    Field('model', placeholder="Model"),
                    Field('vendor',),
                    Field('device_type',),
                    Field('ports', placeholder="Ports"),
                    Field('uplink_speed', placeholder="Uplink Speed"),
                    css_class='col-lg-6'
                ),
            css_class='row'
            ),
            Div(
                Div(
                    HTML("""<input type="submit" name="submit" value="""),
                    HTML('"Add' if self.is_add else '"Update' ),
                    HTML(""" Device Model" class="btn btn-primary"/>"""),
                    HTML("""<a href="{% url 'config:config_settings' %}#device_models" class="btn btn-primary">Cancel</a>"""),
                    HTML("""{% if object %}
                            <a href="{% url 'config:delete_device_model' object.id %}"
                            class="btn btn-danger">
                            Delete <i class="fa fa-trash-o" aria-hidden="true"></i></a>
                            {% endif %}"""),
                    css_class='col-lg-12'
                    ),
                css_class='row'
                ),
        )

DeviceFormSet = inlineformset_factory(DeviceModel, MonitoredResource, form=MonitoredResourceForm, extra=1)

class DeviceFormSetHelper(FormHelper):
    def __init__(self, *args, **kwargs):
        super(DeviceFormSetHelper, self).__init__(*args, **kwargs)
        self.form_method = 'post'
        self.render_required_fields = True
        self.form_id = 'snmp_resource_form'
        self.form_method = 'POST'
        self.add_input(Submit("submit", "Save"))
        self.layout = Layout(
            Div(    
                Div(
                    Field('model'),
                    Field('resource', placeholder="Resource"),
                    css_class='col-lg-6'
                ),
            css_class='row'
            ),
        ) 
class MonitoredResourceForm(forms.ModelForm):
类元:
模型=监视器资源
字段=['resource','model']
定义初始化(self,*args,**kwargs):
self.is_add=kwargs.pop(“is_add”,False)
super(MonitoredResourceForm,self)。\uuuuuu初始化(*args,**kwargs)
self.helper=FormHelper(self)
self.helper.form\u id='snmp\u资源\u表单'
self.helper.form_方法='POST'
self.helper.layout=布局(
分区(
Div(
字段(“模型”),
字段('resource',placeholder=“resource”),
css_class='col-lg-3'
),
css_class='row'
),
Div(
Div(
HTML(“”“”),
HTML(“”“”),
HTML(“{%if对象%}”
{%endif%}“”,
css_class='col-lg-12'
),
css_class='row'
),
)
DeviceFormSet=inlineformset\u工厂(DeviceModel,MonitoredResource,form=MonitoredResourceForm,extra=1)
类DeviceFormSetHelper(FormHelper):
定义初始化(self,*args,**kwargs):
超级(DeviceFormSetHelper,self)。\uuuuuu初始化(*args,**kwargs)
self.form_方法='post'
self.render_必填_字段=True
self.form\u id='snmp\u资源\u form'
self.form_方法='POST'
自我添加输入(提交(“提交”、“保存”))
self.layout=布局(
分区(
Div(
字段(“模型”),
字段('resource',placeholder=“resource”),
css_class='col-lg-6'
),
css_class='row'
),
) 
在我呈现的模板中:

{% block content %} 
{% include "home/form_errors.html" %}
<div class="col-lg-6">
    {% crispy form %}
</div>
<div class="col-lg-6">
    {% crispy formset helper %}
</div>
<!-- /.row -->
{% endblock %}
{%block content%}
{%include“home/form_errors.html”%}
{%crispy form%}
{%crispy formset helper%}
{%endblock%}

有人能看到我丢失了什么吗?

你丢失了一个标签和{{format.management{u form | crispy}}
我想

我想你必须在模板中呈现管理表单

表单集使用管理表单来管理表单集中包含的表单集合。如果不提供此管理数据,将引发异常

将此添加到html视图中

{{ DeviceFormSet.management_form }}

您的问题是表单集中的每个表单都有自己的
管理\u表单
。我没有在crispy中专门讨论过这一点,但在一般的表单集中,这是我遇到的问题。您必须通过迭代或硬编码手动拼出表单集的每一部分,并确保每一部分都有其
management\u表单

我遇到了同样的问题,并在以下列表中找到了答案:


在父窗体中包含一个带有post方法的窗体标记总是很好的。管理窗体是什么标记?据我所知,这是正确的吗?我已经熟悉了我的设备表单和监控资源表单,我想这可能与为每个模型创建单独的表单和提交有关。我如何解决当前的问题?我尝试将{{formset.management_form}}添加到模板中,但它不起作用。我的DeviceForm和MonitoredResourceForm已经升级,我想这可能与创建单独的表单和提交每个模型有关。你能分享你正在使用的Django版本吗?我使用的是1.11版。9@AlexW你是这样加的吗{{deviefrmset.management_form}}在模板中相同?如果不相同,请尝试根据更新答案添加它。如果可以,请在zip中的某个位置共享您的项目代码。
{{ formset.management_form|crispy }}
{% for form in formset %}
    {% crispy form %}
{% endfor %}