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

如何使用Django Form实现批量更新多个用户记录的功能

Django 批量更新用户表单实现方案

1. 定义表单类与Formset

首先在forms.py中定义单个用户的编辑表单,再基于该表单生成批量处理用的表单集:

from django import forms
from django.forms import formset_factory
from .models import User

# 单个用户编辑表单
class UserBatchEditForm(forms.ModelForm):
    # 用户ID设为隐藏字段,提交时用于定位要更新的用户记录
    id = forms.IntegerField(widget=forms.HiddenInput())
    
    class Meta:
        model = User
        # 指定允许批量编辑的字段,可按需调整
        fields = ['id', 'first_name', 'last_name', 'is_contributor', 'is_projectmanager', 'is_administrator']

# 批量表单集,extra=0表示不生成空的新增表单
UserBatchFormSet = formset_factory(UserBatchEditForm, extra=0, can_delete=False)

2. 视图层逻辑处理

在视图中先做权限校验,仅管理员可访问批量编辑功能,同时处理GET/POST请求:

from django.shortcuts import render, redirect
from django.core.exceptions import PermissionDenied
from .models import User
from .forms import UserBatchFormSet

def user_list(request):
    # 权限校验:仅管理员可使用批量编辑功能
    if not request.user.is_administrator:
        # 非管理员返回原只读视图,只传用户列表即可
        users = User.objects.all()
        return render(request, 'readonly_user_list.html', {'users': users})
    
    # 管理员逻辑
    users = User.objects.all().order_by('id')
    if request.method == 'POST':
        formset = UserBatchFormSet(request.POST)
        if formset.is_valid():
            # 遍历所有表单,逐个更新用户
            for form in formset:
                if form.cleaned_data:
                    user = User.objects.get(id=form.cleaned_data['id'])
                    user.first_name = form.cleaned_data['first_name']
                    user.last_name = form.cleaned_data['last_name']
                    user.is_contributor = form.cleaned_data['is_contributor']
                    user.is_projectmanager = form.cleaned_data['is_projectmanager']
                    user.is_administrator = form.cleaned_data['is_administrator']
                    user.save()
            # 保存成功后刷新页面
            return redirect('user_list')
    else:
        # GET请求时,用现有用户数据初始化表单集
        initial_data = [
            {
                'id': user.id,
                'first_name': user.first_name,
                'last_name': user.last_name,
                'is_contributor': user.is_contributor,
                'is_projectmanager': user.is_projectmanager,
                'is_administrator': user.is_administrator
            } for user in users
        ]
        formset = UserBatchFormSet(initial=initial_data)
    # 打包表单和用户数据供模板渲染
    form_user_pairs = zip(formset, users)
    return render(request, 'admin_user_list.html', {'formset': formset, 'form_user_pairs': form_user_pairs})

3. 管理员端模板修改

将原表格替换为表单渲染逻辑,注意必须渲染formset的management_form字段,否则会提交失败:

<div class="card-body">
  <form method="post">
    {% csrf_token %}
    <!-- 必须渲染formset的管理字段 -->
    {{ formset.management_form }}
    <div class="table-responsive">
      <table class="table text-sm mb-0">
        <thead>
          <tr>
            <th>#</th>
            <th>Username</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Is Contributor?</th>
            <th>Is Project Manager?</th>
            <th>Is Administrator?</th>
          </tr>
        </thead>
        <tbody>
          {% for form, user in form_user_pairs %}
          <tr>
            <th scope="row">{{ user.id }}</th>
            <!-- 渲染隐藏的id字段 -->
            <td>{{ form.id }} {{ user.username }}</td>
            <td>{{ form.first_name }}</td>
            <td>{{ form.last_name }}</td>
            <td>{{ form.is_contributor }}</td>
            <td>{{ form.is_projectmanager }}</td>
            <td>{{ form.is_administrator }}</td>
          </tr>
          {% endfor %}
        </tbody>
      </table>
    </div>
    <button type="submit" class="btn btn-success mt-3">保存所有修改</button>
  </form>
</div>

注意事项

  • 布尔字段默认渲染为复选框,若需要下拉选择等其他样式,可在UserBatchEditForm中自定义字段的widget属性
  • 可按需开启formset的can_delete参数,实现批量删除用户的功能
  • 表单校验失败时,Django会自动保留用户已输入的内容并显示错误提示,无需额外处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:54:07