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

Django使用unique_together时如何让双时段选项阻塞单时段重复提交

Django 学生时段申请冲突校验实现方案

你可以通过重写模型的自定义校验方法实现需求,具体实现如下:


步骤1:为模型添加自定义校验逻辑

首先导入校验异常类,之后在你的RequestAStudent模型中重写clean方法,实现冲突判断:

from django.core.exceptions import ValidationError

class RequestAStudent(models.Model):
    PERIODS=(
        ('Academic Network 1', 'Academic Networking 1'),
        ('Academic Network 2', 'Academic Networking 2'),
        ('Both Periods', 'Both Periods'),
    )
    MARK=(
        ('None', 'None'),
        ('Present', 'Present'),
        ('Tardy', 'Tardy'),
        ('X', 'X'),
        ('Absent', 'Absent'),
    )
    # 原有字段保持不变
    student = models.ForeignKey(Student, on_delete= models.CASCADE)
    date_created = models.DateField(auto_now_add=True, null=True)
    Requesting_Teacher = models.ForeignKey(AdvisoryTeacher, on_delete= models.CASCADE)
    Period = models.CharField(max_length=18, null=True, choices = PERIODS)
    teacher = models.ForeignKey(Teacher, verbose_name='Advisory Teacher',default="None", on_delete= models.CASCADE)
    date_requested = models.CharField(max_length=200, verbose_name='Date for Student Request (Use format MMDDYY)', default="2021-11-04",null=True)
    attendance = models.CharField(verbose_name='UPDATE ATTENDANCE HERE!',max_length=18, default="None",choices = MARK)
    owner = models.IntegerField("Request Owner", blank=False, default=1)

    def clean(self):
        # 查询同学生、同申请日期下的所有已有申请,排除当前正在编辑的记录本身
        existed_records = RequestAStudent.objects.filter(
            student=self.student,
            date_requested=self.date_requested
        ).exclude(pk=self.pk)

        # 核心需求逻辑:提交单时段申请时,检查是否已有全时段申请
        if self.Period in ['Academic Network 1', 'Academic Network 2']:
            if existed_records.filter(Period='Both Periods').exists():
                raise ValidationError('该学生当前申请日期已存在全时段申请,无法提交单时段申请')
        
        # 可选补充逻辑:提交全时段申请时,检查是否已有单时段申请,避免冲突
        if self.Period == 'Both Periods':
            if existed_records.filter(Period__in=['Academic Network 1', 'Academic Network 2']).exists():
                raise ValidationError('该学生当前申请日期已存在单时段申请,无法提交全时段申请')

    def __str__(self):
        return "" + str(self.student) + ", Teacher: " + str(self.owner)
    class Meta:
        unique_together = ["student", "Period", "date_requested"]

步骤2:确保校验逻辑触发

  • 如果你使用ModelForm处理前端表单提交,无需额外操作,Django会自动调用clean方法完成校验,错误信息会直接返回到表单页面
  • 如果你直接调用模型save方法操作数据(如shell操作、后台脚本),需要在save前手动调用实例.full_clean()触发校验,也可以重写save方法自动触发:
def save(self, *args, **kwargs):
    self.full_clean()
    super().save(*args, **kwargs)

补充说明

原有unique_together配置可以保留,它仍然负责拦截同一时段的重复申请,和新增的自定义校验逻辑互不冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:45:03