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

Django创建模型实例时如何实现类变量自增且避免重启后计数归零

计数重置原因
  • 你定义在Project模型下的Count是类属性,这类属性的取值只存在于服务运行的进程内存中,不会写入数据库持久存储。当你关闭电脑、重启Django服务时,原有进程的内存数据会被全部清空,新进程启动时会重新加载模型类的代码,自动将Count初始化为你预设的默认值0。
  • 现有写法还存在并发隐患:如果服务开启了多进程/多线程模式,不同进程的内存空间相互隔离,每个进程都会维护自己的Count数值,不仅会出现计数不一致的问题,高并发下还会生成重复的epic_key。
修复方案

需要将计数改为持久化存储的数据库字段,同时加锁避免并发冲突:

  1. 修改models.py中Project模型的定义,新增持久化计数字段:
class Project(models.Model):
    # 新增持久化计数字段
    saga_count = models.IntegerField(default=0, verbose_name="关联Saga计数")
    # 补充你代码中用到的key字段(如果之前已经定义可以忽略这行)
    key = models.CharField(max_length=20, unique=True, verbose_name="项目标识")

    manager = models.ForeignKey(
        User,
        related_name="project_managing",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
    )

修改后需要执行python manage.py makemigrations和python manage.py migrate命令将字段同步到数据库。

  1. 修改signals.py中的信号逻辑,加行锁保证计数的原子性:
from django.db import transaction

@receiver(pre_save, sender=Saga)
def generate_epic_key(sender, instance, *args, **kwargs):
    if not instance.epic_key and instance.epic_project:
        # 开启事务加行锁,避免并发修改导致计数异常
        with transaction.atomic():
            # 锁定当前关联的Project行,其他修改请求会等待锁释放
            project = Project.objects.select_for_update().get(id=instance.epic_project_id)
            current_num = project.saga_count + 1
            instance.epic_key = f"{project.key}-{current_num}"
            project.saga_count = current_num
            # 仅更新计数字段,提高执行效率
            project.save(update_fields=["saga_count"])

调整后计数会持久存储在数据库中,重启服务不会导致计数重置,同时行锁机制也能避免并发场景下的key重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:45:03