Django Crispy 表单 - 更新视图的内联表单集“ManagementForm 数据”错误

     2023-02-24     36

关键词:

【中文标题】Django Crispy 表单 - 更新视图的内联表单集“ManagementForm 数据”错误【英文标题】:Django Crispy forms - inline Formsets 'ManagementForm data' error with update view 【发布时间】:2019-04-22 02:53:17 【问题描述】:

晚上好,

我在使用脆的表格 inlineformset 时遇到了问题。我按照以下指南进行操作:

https://github.com/timhughes/django-cbv-inline-formset/blob/master/music/views.py https://django-crispy-forms.readthedocs.io/en/latest/crispy_tag_formsets.html#formsets

编辑 我认为这个问题与双提交按钮有关。 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'
            ),
        ) 

在我渲染的模板中:

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

有人能看到我遗漏了什么吗?

【问题讨论】:

如果可以的话,在某个地方分享你的项目代码。 【参考方案1】:

我遇到了同样的问题,在documentation找到了答案:

 formset.management_form|crispy 
% for form in formset %
    % crispy form %
% endfor %

【讨论】:

【参考方案2】:

您的问题是表单集中的每个表单都有自己的management_form。我没有在脆皮中专门处理这个问题,但在一般的表格中,这就是我遇到的问题。您必须通过迭代或硬编码手动拼出表单集的每一部分,并确保每个部分都有其management_form

【讨论】:

【参考方案3】:

我认为您必须在模板中呈现管理表单,explained here why you need that

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

在视图 html 中添加这个

 DeviceFormSet.management_form 

【讨论】:

如何解决我当前的问题?我尝试将 formset.management_form 添加到模板中,但没有成功 我添加了我的 DeviceForm 和 MonitoredResourceForm,我认为这可能与它为每个模型创建单独的表单和提交有关? 能分享一下你使用的Django版本吗? 我使用的是 1.11.9 版本 @AlexW 你有没有像 DeviceFormSet.management_form 一样在模板中添加它?如果没有,请尝试根据更新答案添加它。【参考方案4】:

你缺少一个标签,还有 format.management_form|crispy 我猜

【讨论】:

在父表单中包含一个带有 post 方法的表单标签总是很好的。管理表单是必须的 什么标签?根据我从脆皮文件中的理解,它是正确的吗? django-crispy-forms.readthedocs.io/en/latest/… 我添加了我的 DeviceForm 和 MonitoredResourceForm,我认为这可能与它为每个模型创建单独的表单和提交有关?

Django:模板中的 Crispy 表单验证错误

】Django:模板中的Crispy表单验证错误【英文标题】:Django:CrispyFormsValidationErrorinTemplate【发布时间】:2021-02-1107:43:10【问题描述】:我正在使用django-crispy-forms来呈现精美的表单。对于我的一个表单,我必须进行一些自定义调整,... 查看详情

使用 Django 模型表单 + 表单向导 + Crispy - 不进行第二步

】使用Django模型表单+表单向导+Crispy-不进行第二步【英文标题】:UsingDjangomodelforms+formwizard+Crispy-Doesnotproceedtosecondstep【发布时间】:2014-12-3122:52:26【问题描述】:我对django中的表单相当陌生。我的问题是我有一些非常大的模型,... 查看详情

Django Crispy 表单提交按钮

】DjangoCrispy表单提交按钮【英文标题】:DjangoCrispyFormSubmitButton【发布时间】:2017-07-0823:01:45【问题描述】:我正在尝试使用CrispyForms使我的表单看起来不错。我的forms.py中有以下内容:fromdjangoimportformsfrom.modelsimportTeamfromcrispy_forms... 查看详情

Django Crispy 表单拆分字段布局

】DjangoCrispy表单拆分字段布局【英文标题】:DjangoCrispyFormSplitFieldLayouts【发布时间】:2013-07-2101:30:08【问题描述】:我们有一个清晰的表单,我们希望能够在表单HTML模板的不同部分呈现不同的字段,但是我们在CrispyDocumentation中... 查看详情

使用内联表单在 django-crispy-forms 中呈现字段错误

】使用内联表单在django-crispy-forms中呈现字段错误【英文标题】:Renderingfielderrorsindjango-crispy-formswithinlineforms【发布时间】:2013-10-0608:39:35【问题描述】:我在django_crispy_forms中使用bootstrap3作为默认模板包,并尝试使用脆标签呈现... 查看详情

Django Crispy 表单根据需要设置模型字段

】DjangoCrispy表单根据需要设置模型字段【英文标题】:DjangoCrispyformsetmodelfieldasrequired【发布时间】:2018-04-1820:27:38【问题描述】:我有一个模型表单,我想在其中将required属性设置为True以进行电子邮件验证字段:-emailclassRegisterMy... 查看详情

在 python 中通过 django-crispy-forms 渲染表单

】在python中通过django-crispy-forms渲染表单【英文标题】:Renderingformsthroughdjango-crispy-formsinpython【发布时间】:2012-06-2910:38:19【问题描述】:我们需要在python中渲染表单并捕获html输出。到目前为止,我们使用的是肮脏的hack:defcrispy... 查看详情

替代 django-crispy-forms

】替代django-crispy-forms【英文标题】:alternativetodjango-crispy-forms【发布时间】:2019-07-3101:21:15【问题描述】:我正在django2.1中开发一个应用程序并使用bootstrap4这需要用户注册表格。在我看到的大多数示例中,都显示了单列表单的... 查看详情

删除 Django Crispy 表单中的标签

】删除DjangoCrispy表单中的标签【英文标题】:RemoveLabelsinaDjangoCrispyForms【发布时间】:2012-07-1310:08:52【问题描述】:有人知道是否有正确的方法可以去除脆皮标签吗?我已经做到了:self.fields[\'field\'].label=""但这不是一个很好的解... 查看详情

Django Crispy Forms 向 ModelFormSet 添加新的空表单

】DjangoCrispyForms向ModelFormSet添加新的空表单【英文标题】:DjangoCrispyFormsAddNewEmptyFormtoModelFormSet【发布时间】:2018-02-1018:28:57【问题描述】:向具有现有表单的模型表单集添加新的空表单的最简单方法是什么?forms.py:classMyForm(Mode... 查看详情

无法使用 django-crispy 表单在同一行显示标签和字段

】无法使用django-crispy表单在同一行显示标签和字段【英文标题】:Cannotdisplaylabelandfieldonsamelineusingdjango-crispyforms【发布时间】:2016-07-1216:40:55【问题描述】:我试图将我的字段标签放在表单的左侧,右侧有文本输入。但是,我似... 查看详情

在 django-crispy 按钮名称中使用 django 模板变量

】在django-crispy按钮名称中使用django模板变量【英文标题】:Useadjangotemplatevariableindjango-crispybuttonname【发布时间】:2012-08-2912:49:45【问题描述】:我正在使用django-crispy-forms来生成与Bootstrap兼容的表单。对于表单提交,我的forms.py... 查看详情

Django 视图和表单提交按钮更新数据库

】Django视图和表单提交按钮更新数据库【英文标题】:Djangoviewsandformssubmitbuttonupdatedatabase【发布时间】:2012-12-0909:04:40【问题描述】:这是提交按钮所在的表单。<form><buttontype="submit"name="subscribe"class="btnbtn-primarypull-right">... 查看详情

Django 表单:查询结果定义的字段,单个视图同时更新多个对象

】Django表单:查询结果定义的字段,单个视图同时更新多个对象【英文标题】:Djangoform:fieldsdefinedbyqueryresult,singleviewtoupdatemultipleobjectssimultaneously【发布时间】:2016-07-1819:26:50【问题描述】:我在一个Django1.8项目中有以下模型:cl... 查看详情

如何使用 Ajax 渲染 django-crispy-forms 的验证错误?

】如何使用Ajax渲染django-crispy-forms的验证错误?【英文标题】:Howtorenderingvalidationerrorsofdjango-crispy-formswithAjax?【发布时间】:2020-08-2800:57:30【问题描述】:我想用ajax显示Django默认表单错误。如果有一些错误,这里的代码应该显示... 查看详情

Django 在基于类的视图中处理多个表单

】Django在基于类的视图中处理多个表单【英文标题】:Djangohandlemultipleformsinclassbasedview【发布时间】:2016-12-0506:36:05【问题描述】:我有一个用于更新用户个人资料信息的更新视图。在该页面上,我添加了另一个单独的密码更改... 查看详情

Django Crispy Forms - 通过 Helper 添加按钮

】DjangoCrispyForms-通过Helper添加按钮【英文标题】:DjangoCrispyForms-AddButtonviaHelper【发布时间】:2012-04-2520:46:27【问题描述】:我研究了Crispy-Forms文档,并尝试在我的一个表单中添加一个额外的按钮。与self.helper.add_input(Button(\'back\',"... 查看详情

Django Crispy Forms 重新排列布局并保留 Bootstrap 内联格式?

】DjangoCrispyForms重新排列布局并保留Bootstrap内联格式?【英文标题】:DjangoCrispyFormsrearrangelayoutandretainBootstrapinlineformatting?【发布时间】:2014-02-2607:48:19【问题描述】:我目前正在处理一个Django项目,并且正在使用cripsy-forms与Bootst... 查看详情