Django Forms与Formset编辑FBV无法保存数据问题求助
问题
尝试创建一个基于函数的视图(FBV)用于编辑数据,但编辑内容无法保存。终端显示有POST响应,但数据未保存且未跳转到home页面。相关代码如下:
views.py
def editplayform(request,id): play = Play.objects.get(id=id) if request.method =='POST': form = forms.PlayForm(request.POST, instance=play) time_shown_formset = forms.TimeShownFormSet(request.POST, instance=play) if form.is_valid() and time_shown_formset.is_valid(): form.save() time_shown_formset.save() return redirect("play:home") else: form = forms.PlayForm(instance=play) time_shown_formset = forms.TimeShownFormSet(instance=play) return render(request, 'play/fbvplayform.html', context={'form':form, "time_shown_formset":time_shown_formset, 'play':play})
edit.html
<form method="POST"> {% csrf_token %} <h1>Edit PLAY</h1> <div>{{ form.non_form_errors }} {{ form.as_p }}</div> <h1>Edit Timeshown</h1> <!-- prettier-ignore --> {{ time_shown_formset.non_form_errors }} {{ time_shown_formset.management_form}} {% for form in time_shown_formset %} <div>{{ form.times.label }}: {{ form.times }}</div> {% if time_shown_formset.can_delete %} <div>{{ form.DELETE }} {{ form.DELETE.label }}</div> {% endif %} {% endfor %} <div> <button type="submit">Update Play</button> </div> </form>
排查与解决
1. 表单/表单集验证失败(最可能原因)
只有表单和表单集都验证通过,才会执行保存和跳转逻辑。可以通过以下方式排查:
- 在视图的POST分支中添加错误打印,直接查看终端输出:
if request.method =='POST': form = forms.PlayForm(request.POST, instance=play) time_shown_formset = forms.TimeShownFormSet(request.POST, instance=play) if form.is_valid() and time_shown_formset.is_valid(): form.save() time_shown_formset.save() return redirect("play:home") # 添加错误打印 else: print("表单错误:", form.errors) print("表单集错误:", time_shown_formset.errors) - 在模板中补充字段级错误显示,方便前端查看:
替换原表单渲染部分:
表单集子表单也要补充错误显示:<div> {% for field in form %} <div>{{ field.label }}: {{ field }}</div> {% if field.errors %} <div style="color:red;">{{ field.errors }}</div> {% endif %} {% endfor %} </div>{% for form in time_shown_formset %} <div> {{ form.times.label }}: {{ form.times }} {% if form.times.errors %} <div style="color:red;">{{ form.times.errors }}</div> {% endif %} </div> {% if time_shown_formset.can_delete %} <div>{{ form.DELETE }} {{ form.DELETE.label }}</div> {% endif %} {% endfor %}
2. 表单集未处理文件字段
如果TimeShown模型包含FileField或ImageField,需要在视图中传递request.FILES,同时修改表单的enctype属性:
- 视图中修改表单集初始化:
time_shown_formset = forms.TimeShownFormSet(request.POST, request.FILES, instance=play) - 模板中修改表单标签:
<form method="POST" enctype="multipart/form-data">
3. 路由命名空间或跳转目标错误
检查redirect("play:home")中的命名空间play是否在URL配置中正确定义,home对应的URL是否存在。可以先尝试用绝对路径跳转测试:
return redirect("/home/")
4. 数据库事务异常
如果手动开启了数据库事务且未提交,可能导致数据不保存。可以尝试在保存后手动提交(Django默认自动提交,此情况较少见):
from django.db import transaction # 保存后添加 transaction.commit()
内容的提问来源于stack exchange,提问作者Israel
相关产品推荐
相关产品推荐

