You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django modelformset无法编辑、保存或删除数据问题求助

问题核心原因

你当前的实现混用了Django单表单类视图CreateView的逻辑和modelformset的批量操作逻辑,核心错误点有4个:

  1. GET请求初始化formset时没有传入已有数据的查询集,页面不会渲染已存储的Driver记录,自然无法编辑删除
  2. POST请求校验formset时没有绑定查询集,Django无法识别哪些是需要更新/删除的已有实例
  3. 模板中错误渲染了单表单的隐藏字段,没有渲染formset中每个子表单的隐藏ID字段,导致提交时所有数据都被识别为新实例
  4. 开启了can_delete=True但没有在模板中渲染删除复选框,无法标记需要删除的记录
修复步骤

1. 修正视图逻辑(views.py)

弃用CreateView自带的单表单逻辑,直接基于View重写适配formset的get/post方法:

from django.views.generic import View
from django.shortcuts import render, redirect

class DriverView(LoginRequiredMixin, View):
    template_name = 'trucking/driver_form.html'

    def get(self, request, *args, **kwargs):
        # 绑定已有Driver数据到formset,用于编辑
        formset = DriverFormSet(queryset=Driver.objects.all())
        return render(request, self.template_name, {'formset': formset})

    def post(self, request, *args, **kwargs):
        # 提交时同样绑定查询集,让Django识别已有实例
        formset = DriverFormSet(request.POST, queryset=Driver.objects.all())
        if formset.is_valid():
            # 自动处理新增、更新、标记删除的记录
            formset.save()
            if request.POST.get('Save_Exit'):
                return redirect('/database/')
            if request.POST.get('Save'):
                return redirect('/driver/')
        return render(request, self.template_name, {'formset': formset})

2. 修正路由配置(urls.py)

对应更新视图类名即可:

urlpatterns = [
    path('driver/', DriverView.as_view(), name = "driver-create"),
]

3. 修正模板代码(driver_form.html)

  • 删除无效的单表单隐藏字段渲染逻辑
  • 为每个formset子表单渲染隐藏字段(包含实例ID)
  • 自动渲染删除复选框
    修改后的模板核心部分:
<form method = "POST">
    <fieldset class = "form-group">
    {% csrf_token %}
    {{ formset.management_form }}
    {{ formset.non_form_errors }}
    
    <table cellpadding="6" cellspacing="1" border="0">
        <tbody>
    {% for form in formset %}
        <!-- 渲染每个子表单的隐藏字段(包含实例ID) -->
        {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
        {% for field in form.visible_fields %}
        <tr>    
            <td class="column_name">{{field.label_tag}}{{field.auto_id}}</td>
            <td class="column_data">{{field}}</td>
            <td class="column_errors">{{field.errors|striptags}}</td>
        </tr>
        {% endfor %}
    {% endfor %}
        <tr>
            <td colspan = "2" class="column_submit">
                <input type="submit" name="Save_Exit" value="Save & Exit" class="submit">
                <input type="submit" name="Save" value="Save" class="submit">
                <a href="{% url 'database'%}"><input type="button" name="Cancel" value="Cancel" class="submit"></a>
            </td>
        </tr> 
    </tbody>
</table>
</fieldset>
</form>

4. 表单文件无需修改

现有forms.py的配置已经满足需求,保留can_delete=True即可。

内容的提问来源于stack exchange,提问作者Fomorian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:36:05