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

如何在Django模型中设置三个字段为联合唯一约束?

实现Django Answer模型的联合唯一性约束

要实现同一用户在同一考试中对同一问题只能提交一次答案的需求,你可以通过在Answer模型中添加联合唯一性约束来实现,同时数据库层面也会同步生成约束,从根源避免重复记录。

方法一:使用unique_together(兼容Django旧版本)

在模型的Meta类中定义unique_together,指定需要联合唯一的字段组合:

class Answer(models.Model):
    exam      = models.ForeignKey(Exam, on_delete=models.CASCADE, default=None)
    user      = models.ForeignKey(User, on_delete=models.CASCADE)
    question  = models.ForeignKey(Question, on_delete=models.CASCADE)
    answer    = models.CharField(max_length=8)

    class Meta:
        # 约束user、exam、question三个字段的组合唯一
        unique_together = ('user', 'exam', 'question')

方法二:使用UniqueConstraint(Django 2.2+ 推荐用法)

unique_together在Django新版本中已被标记为过时,推荐使用constraints中的UniqueConstraint,功能更灵活:

class Answer(models.Model):
    exam      = models.ForeignKey(Exam, on_delete=models.CASCADE, default=None)
    user      = models.ForeignKey(User, on_delete=models.CASCADE)
    question  = models.ForeignKey(Question, on_delete=models.CASCADE)
    answer    = models.CharField(max_length=8)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'exam', 'question'],
                name='unique_user_exam_question'  # 自定义约束名称,方便后续识别
            )
        ]

生效步骤

修改模型后,需要执行数据库迁移命令,让约束生效:

python manage.py makemigrations
python manage.py migrate

效果与异常处理

当尝试保存重复的user+exam+question组合时,Django会抛出django.db.utils.IntegrityError异常。你可以在视图或业务逻辑中捕获这个异常,给用户返回友好提示:

from django.db import IntegrityError

# 示例:处理答题提交
try:
    Answer.objects.create(
        user=current_user,
        exam=target_exam,
        question=target_question,
        answer=user_answer
    )
except IntegrityError:
    # 这里可以返回"你已经提交过这道题的答案"之类的提示
    pass

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:01:01