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

Django多用户审批表单开发疑问:多对多字段与INSTANCE更新困惑

解决Django多用户审批表单的UpdateView同步问题

嘿,这个问题我之前帮朋友处理过类似的,核心问题出在你让所有用户直接操作同一个主模型实例了!多用户审批场景下,每个审批人应该有属于自己的独立修改/审批记录,而不是直接改动原始表单——不然肯定会出现一人修改全平台同步的情况。下面给你一步步拆解解决方案:

1. 调整数据模型:新增用户专属审批实例

首先要重构你的模型,把「公共主表单」和「用户专属审批记录」分开。主表单存公共基础信息,每个审批用户对应一条独立的审批实例,用来保存他的修改内容、审批状态等。示例代码如下:

from django.db import models
from django.contrib.auth.models import User

# 主表单模型:存储所有用户共享的基础信息
class MainApprovalForm(models.Model):
    title = models.CharField(max_length=200, verbose_name="表单标题")
    description = models.TextField(verbose_name="表单描述")
    created_at = models.DateTimeField(auto_now_add=True)
    # 关联所有需要审批的用户
    approvers = models.ManyToManyField(User, related_name="assigned_approval_forms")

# 用户专属审批实例:每个用户对同一个主表单有且仅有一条记录
class UserApprovalRecord(models.Model):
    main_form = models.ForeignKey(
        MainApprovalForm, 
        on_delete=models.CASCADE, 
        related_name="user_approval_records"
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    # 这里放用户需要修改/填写的字段,和主表单对应或按需调整
    user_modified_content = models.TextField(blank=True, verbose_name="我的修改内容")
    approval_status = models.CharField(
        max_length=20,
        choices=[("pending", "待审批"), ("approved", "已同意"), ("rejected", "已驳回")],
        default="pending",
        verbose_name="审批状态"
    )
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        # 强制每个用户对同一个主表单只能有一条审批记录
        unique_together = ("main_form", "user")

2. 重写UpdateView:绑定当前用户的专属实例

接下来修改你的UpdateView逻辑,不再直接操作MainApprovalForm,而是自动获取/创建当前用户对应的UserApprovalRecord实例。这样每个用户修改的都是自己的专属记录,不会干扰其他人:

from django.views.generic.edit import UpdateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse
from .models import UserApprovalRecord, MainApprovalForm

class UserApprovalUpdateView(LoginRequiredMixin, UpdateView):
    model = UserApprovalRecord
    fields = ["user_modified_content", "approval_status"]
    template_name = "approval_form_update.html"

    def get_object(self, queryset=None):
        # 从URL参数里获取主表单ID
        main_form_id = self.kwargs.get("main_form_id")
        main_form = MainApprovalForm.objects.get(id=main_form_id)
        # 获取当前用户的审批记录,不存在则自动创建(首次打开表单时初始化)
        obj, created = UserApprovalRecord.objects.get_or_create(
            main_form=main_form,
            user=self.request.user
        )
        return obj

    def get_success_url(self):
        # 提交成功后跳转回审批列表(可根据你的需求修改)
        return reverse("approval_dashboard")

3. 模板与前端适配

你的模板里要渲染的是UserApprovalRecord的字段,而不是主表单的字段。如果需要展示主表单的原始内容,可以在模板里通过{{ object.main_form.title }}这样的方式关联读取,确保用户既能看到原始信息,又能修改自己的专属内容。

额外小贴士

  • 如果需要汇总所有审批意见或查看主表单的整体审批状态,可以通过MainApprovalForm的user_approval_records关联查询所有用户的审批记录,做统计展示。
  • 可以给UserApprovalRecord添加权限控制,确保用户只能修改自己的审批记录,不能操作他人的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:33:45