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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:22:23