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

如何在Django中管理员批准前临时保存数据库更新请求?

这是个很典型的用户内容审核场景,我来给你分享几个更灵活的实现思路,应该能解决你之前提到的痛点:

方案1:通用审核请求模型(首推)

这个思路能完美解决多模型场景的复用问题,不用给每个需要审核的模型单独建表,而且不会污染原模型的结构。核心是利用Django的ContentType通用关联来记录任意模型的修改请求,再用JSON字段存储具体的修改内容。

模型定义

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.auth.models import User

class PendingChange(models.Model):
    # 关联被修改的目标实例(支持任意模型)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    
    # 存储具体的修改内容:键是字段名,值是修改后的新值
    changes = models.JSONField()
    
    # 提交信息
    submitted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    submitted_at = models.DateTimeField(auto_now_add=True)
    
    # 审核状态
    STATUS_CHOICES = [
        ('pending', '待审核'),
        ('approved', '已通过'),
        ('rejected', '已拒绝'),
    ]
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    
    # 审核信息
    reviewed_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='reviewed_changes')
    reviewed_at = models.DateTimeField(null=True, blank=True)

    def __str__(self):
        return f"修改请求:{self.content_object} - {self.submitted_by}"

工作流程

  1. 用户提交修改:
    用户在表单里填写完修改内容后,后端不直接更新MyModel实例,而是:

    • 获取原实例的当前数据
    • 对比表单提交的数据,提取出有变化的字段和新值(比如只记录description的修改)
    • 创建一个PendingChange实例,关联到目标MyModel,把变化内容存入changes字段

    示例代码(视图里的逻辑):

    def submit_edit(request, model_id):
        instance = MyModel.objects.get(id=model_id)
        form = MyModelEditForm(request.POST, instance=instance)
        if form.is_valid():
            # 提取有变化的字段
            changes = {}
            for field in form.changed_data:
                changes[field] = form.cleaned_data[field]
            # 创建审核请求
            PendingChange.objects.create(
                content_object=instance,
                changes=changes,
                submitted_by=request.user if request.user.is_authenticated else None
            )
            # 返回成功提示
            return HttpResponseRedirect('/success/')
    
  2. 管理员审核:

    • 在管理员后台(可以用Django Admin自定义页面,或者自己写视图)列出所有status='pending'的修改请求
    • 每个请求可以展示原实例的当前值和修改后的新值(方便对比)
    • 点击「批准」时,遍历changes字段的键值对,更新原实例对应的字段,然后把PendingChange的status设为approved,记录审核者和时间
    • 点击「拒绝」时,直接修改status为rejected即可

优势

  • 完全通用:支持所有需要审核的模型,不用重复建表
  • 数据干净:原模型不需要添加额外字段,所有修改请求都集中在一个表管理
  • 记录清晰:能准确看到每个修改请求的目标实例、修改内容、提交人、审核状态

补充优化建议

  • 提交修改时,只记录有变化的字段,避免存储冗余数据
  • 管理员审核页面可以做字段对比展示(比如用diff效果),更直观
  • 可以给PendingChange加一个note字段,让用户填写修改原因,帮助管理员判断
  • 审核通过/拒绝后,可以给提交用户发送通知(比如站内信或邮件)

对比你之前的方案

  • 比「专用EditToMyModel模型」更灵活,不用为每个模型单独建表,维护成本更低
  • 比「给原模型加额外字段」更清晰,不会把审核状态和原业务数据混在一起,原模型的职责更单一

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:37:39