You need to enable JavaScript to run this app. Django项目中如何实现表单更新需指定用户审批后展示
优惠活动
大模型
产品
解决方案
定价
更多

Django项目中如何实现表单更新需指定用户审批后展示

核心实现方案

当前代码的核心缺陷是Lead提交更新时直接通过form.save()覆盖正式生效的DoaTable数据,没有审批状态隔离,导致未审核内容直接对外生效。可以按照以下分层逻辑改造,全程保持系统轻量:

模型层改造

在现有模型基础上新增审批状态字段,拆分“正式生效数据”和“待审批草稿”两个数据层级:

# approvals/models.py
class DoaTable(models.Model):
    LIMITS = (
        ('Low Risk', 'Low Risk'),
        (...),
        ('Strict Credit Check', 'Strict Credit Check'),
        ('No Credit Check', 'No Credit Check'),
    )

    RANKS = (
        ('Analyst', 'Analyst'),
        ('Senior Analyst', 'Senior Analyst'),
        ('Lead', 'Lead'),
        ('Manager', 'Manager'),
        ('...Officer'),
    )
    rank = models.CharField(max_length=200, choices=RANKS)
    risk = models.CharField(max_length=200, choices=LIMITS)
    limit = models.FloatField()
    comp_name = models.ForeignKey(CompanyProfile, on_delete=models.CASCADE, null=True)
    
    # 新增审批相关字段
    is_approved = models.BooleanField(default=True, verbose_name="是否为已审批正式数据")
    submitted_by = models.ForeignKey(
        UserProfile,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        verbose_name="草稿提交人"
    )

    class Meta:
        # 约束:同公司、同职级、同风险维度仅能存在1条已审批的正式数据
        unique_together = [("comp_name", "rank", "risk", "is_approved")]

视图层逻辑改造

Lead提交更新逻辑

去掉原有直接覆盖正式数据的保存逻辑,Lead提交内容时仅生成待审批草稿,不直接修改正式数据:

# approvals/views.py
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden

@login_required
def update_limit(request, id):
    # 身份校验:仅Lead可提交更新申请
    if request.user.rank != "Lead":
        return HttpResponseForbidden("无提交权限")
    
    # 获取正式生效的额度记录,直接过滤掉草稿数据
    limiting = get_object_or_404(DoaTable, id=id, is_approved=True)
    form = UpdateDoaTableForm(request.POST or None)

    if form.is_valid():
        # 不直接绑定原实例保存,创建全新草稿
        draft = form.save(commit=False)
        # 继承正式记录的关联属性,仅使用Lead修改的limit值
        draft.rank = limiting.rank
        draft.risk = limiting.risk
        draft.comp_name = limiting.comp_name
        draft.is_approved = False
        draft.submitted_by = request.user
        draft.save()
        return redirect('approvals:my_draft_list')

    context = {
        'form': form,
        'limiting_item': limiting
    }
    return render(request, 'limitUpdate.html', context)

注意:禁止在Lead提交时使用关联了正式DoaTable实例的表单保存逻辑,否则会直接覆盖正式生效的数据。

Manager审批逻辑

新增审批视图,仅向Manager展示待审批草稿列表,提供通过/驳回两个操作分支:

@login_required
def process_draft(request, draft_id):
    # 身份校验:仅Manager可执行审批操作
    if request.user.rank != "Manager":
        return HttpResponseForbidden("无审批权限")
    
    draft = get_object_or_404(DoaTable, id=draft_id, is_approved=False)
    if request.method == "POST":
        action = request.POST.get("action")
        if action == "approve":
            # 删除同维度的旧正式数据
            DoaTable.objects.filter(
                comp_name=draft.comp_name,
                rank=draft.rank,
                risk=draft.risk,
                is_approved=True
            ).delete()
            # 将当前草稿转为正式生效数据
            draft.is_approved = True
            draft.save()
        elif action == "reject":
            # 驳回则直接删除草稿
            draft.delete()
        return redirect("approvals:draft_approval_list")
    
    return render(request, "draft_approval.html", {"draft": draft})

对外展示规则

所有面向普通用户、前端页面的正式额度查询,必须在ORM层加is_approved=True的过滤条件,从根源上避免草稿数据被泄露展示:

  • 统一查询写法示例:DoaTable.objects.filter(is_approved=True, comp_name=当前关联公司)
  • 禁止在全表查询后再做内存过滤,避免漏判草稿数据

轻量优化:Lead提交新草稿时,可自动删除该Lead针对同维度正式额度提交的旧未审批草稿,避免审批列表出现重复申请


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.05 18:27:04