Django modelformset无法编辑、保存或删除数据问题求助
问题核心原因
你当前的实现混用了Django单表单类视图CreateView的逻辑和modelformset的批量操作逻辑,核心错误点有4个:
- GET请求初始化formset时没有传入已有数据的查询集,页面不会渲染已存储的Driver记录,自然无法编辑删除
- POST请求校验formset时没有绑定查询集,Django无法识别哪些是需要更新/删除的已有实例
- 模板中错误渲染了单表单的隐藏字段,没有渲染formset中每个子表单的隐藏ID字段,导致提交时所有数据都被识别为新实例
- 开启了
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
相关产品推荐
相关产品推荐

