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
相关产品推荐
相关产品推荐

