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

如何限制TrainingPlan中TrainingUnit及TrainingUnit中Exercise的添加数量?

解决方案

一、限制单个TrainingPlan最多包含12个TrainingUnit

在TrainingUnit模型中添加验证逻辑,确保关联的训练计划下的单元总数不超过12。通过重写clean方法做校验,并在save时强制触发验证,避免直接调用save()绕过检查:

class TrainingUnit(models.Model):
    trainingplan = models.ForeignKey(TrainingPlan, on_delete=models.CASCADE)

    def clean(self):
        super().clean()
        # 统计当前训练计划下已有的单元数量
        unit_count = TrainingUnit.objects.filter(trainingplan=self.trainingplan).count()
        # 新建单元时,检查总数是否即将超过12
        if self.pk is None and unit_count >= 12:
            raise ValidationError("单个训练计划最多只能添加12个训练单元")

    def save(self, *args, **kwargs):
        self.full_clean()  # 触发所有验证逻辑
        super().save(*args, **kwargs)

二、限制单个TrainingUnit的Exercise数量在3-5之间

在Exercise模型中添加校验,确保训练单元下的动作数量符合3-5的要求,同时可选添加删除拦截,防止数量低于下限:

1. 添加动作时的上限校验

class Exercise(models.Model):
    trainingunit = models.ForeignKey(TrainingUnit, on_delete=models.CASCADE)
    exercisename = models.CharField(max_length=100, verbose_name="Exercise", choices=EXERCISE_CHOICES)
    exercisesets = models.IntegerField(choices=SETSCHOICES)
    exercisereps = models.IntegerField(choices=REPCHOICES)

    def clean(self):
        super().clean()
        exercise_count = Exercise.objects.filter(trainingunit=self.trainingunit).count()
        # 新建动作时,检查总数是否即将超过5
        if self.pk is None and exercise_count >= 5:
            raise ValidationError("单个训练单元最多只能添加5个训练动作")

    def save(self, *args, **kwargs):
        self.full_clean()
        super().save(*args, **kwargs)

2. 防止动作数量低于3的删除拦截

如果需要确保训练单元始终至少有3个动作,可以通过pre_delete信号拦截非法删除:

from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django.core.exceptions import ValidationError

@receiver(pre_delete, sender=Exercise)
def prevent_exercise_under_min(sender, instance, **kwargs):
    training_unit = instance.trainingunit
    # 计算删除后剩余的动作数量
    remaining_count = Exercise.objects.filter(trainingunit=training_unit).count() - 1
    if remaining_count < 3:
        raise ValidationError("单个训练单元至少需要保留3个训练动作,无法继续删除")

3. 可选:训练单元的下限校验

也可以在TrainingUnit模型中添加校验,确保保存时关联的动作数量不低于3:

class TrainingUnit(models.Model):
    trainingplan = models.ForeignKey(TrainingPlan, on_delete=models.CASCADE)

    def clean(self):
        super().clean()
        # 保留之前的训练计划数量校验逻辑
        unit_count = TrainingUnit.objects.filter(trainingplan=self.trainingplan).count()
        if self.pk is None and unit_count >= 12:
            raise ValidationError("单个训练计划最多只能添加12个训练单元")
        
        # 新增动作数量下限校验
        exercise_count = Exercise.objects.filter(trainingunit=self).count()
        if exercise_count < 3:
            raise ValidationError("单个训练单元至少需要添加3个训练动作")

    def save(self, *args, **kwargs):
        self.full_clean()
        super().save(*args, **kwargs)

注意事项

  • 模型层的校验是后端的最后一道防线,能有效避免前端绕过限制的情况。
  • 如果使用Django表单,可以在表单层同步添加校验逻辑,给用户更及时的前端提示。
  • 所有ValidationError的提示信息可以根据实际需求调整,让用户更容易理解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:10:51