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

如何在Django模板中更新列表内的单个模型数据项

解决方案

首先明确你现有代码无法正常运行的核心原因:

  1. 模型名不匹配:models.py中定义的是Foo模型,但视图中查询的是Person类,导致数据源错误
  2. 未传递条目主键:后端接收请求时无法定位需要更新的具体模型实例
  3. HTML结构不规范:form标签直接放在<tr>外会被浏览器自动移出表格范围,表单与提交按钮无法关联

下面分两种场景给出可直接运行的实现方案:


方案1:单条目独立提交(每个修改按钮单独提交对应条目)

步骤1:定义表单类(forms.py)

from django import forms
from .models import Foo

class FooUpdateForm(forms.ModelForm):
    class Meta:
        model = Foo
        fields = ["foo"]

步骤2:修改视图逻辑(views.py)

from django.shortcuts import render, redirect, get_object_or_404
from .models import Foo
from .forms import FooUpdateForm

def my_view(request):
    # 处理POST更新请求
    if request.method == "POST":
        # 从表单隐藏字段获取当前条目的主键
        target_id = request.POST.get("target_id")
        instance = get_object_or_404(Foo, pk=target_id)
        # 绑定表单数据与实例
        form = FooUpdateForm(request.POST, instance=instance)
        if form.is_valid():
            form.save()
            # 重定向到当前页刷新数据
            return redirect("my_view")
    
    # GET请求加载数据
    foo_list = Foo.objects.all()
    context = {
        "foo_list": foo_list,
        "form": FooUpdateForm()
    }
    return render(request, "my_app/my_view.html", context)

注意:需要在你的路由配置中给该视图添加name="my_view",保证重定向正常生效

步骤3:修改模板代码(my_view.html)

<table>
  <tr>
    <th>bar</th>
    <th>当前foo值</th>
    <th>修改foo</th>
    <th>操作</th>
  </tr>
  {% for item in foo_list %}
  <tr>
    <td>{{ item.bar }}</td>
    <td>{{ item.foo }}</td>
    <td>
      <form method="post" style="margin:0;">
        {% csrf_token %}
        <!-- 隐藏字段传递当前条目主键 -->
        <input type="hidden" name="target_id" value="{{ item.pk }}">
        {{ form.foo }}
    </td>
    <td style="width: 5%;">
        <button type="submit">修改</button>
      </form>
    </td>
  </tr>
  {% endfor %}
</table>

方案2:批量更新(修改多个条目后统一提交)

如果需要支持同时修改多个条目再统一保存,可以使用Django内置的ModelFormset,减少重复提交次数:

视图逻辑(views.py)

from django.shortcuts import render, redirect
from django.forms import modelformset_factory
from .models import Foo

def my_view(request):
    # 生成Foo模型的表单集,仅包含foo字段,不显示额外空表单
    FooFormSet = modelformset_factory(Foo, fields=("foo",), extra=0)
    if request.method == "POST":
        formset = FooFormSet(request.POST)
        if formset.is_valid():
            formset.save()
            return redirect("my_view")
    else:
        formset = FooFormSet(queryset=Foo.objects.all())
    return render(request, "my_app/my_view.html", {"formset": formset})

模板代码(my_view.html)

<form method="post">
  {% csrf_token %}
  <!-- 表单集管理字段(必须保留) -->
  {{ formset.management_form }}
  <table>
    <tr>
      <th>bar</th>
      <th>foo</th>
    </tr>
    {% for form in formset %}
    <tr>
      <td>{{ form.instance.bar }}</td>
      <td>
        {{ form.foo }}
        <!-- 表单自动生成的主键隐藏字段,必须保留 -->
        {{ form.id }}
      </td>
    </tr>
    {% endfor %}
  </table>
  <button type="submit">保存所有修改</button>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:15:04