Django三字段唯一约束失效,如何实现用户每日每题仅答一次?
解决方案
你的问题出在原约束用了精确到秒的created_at字段——哪怕同一用户同一天同一问题,只要提交时间差几秒,约束就不会触发。要实现按日期限制,得把时间字段截断到日期维度,用Django的TruncDate函数配合唯一约束来实现。
步骤1:导入必要的函数
在模型文件顶部导入TruncDate:
from django.db.models.functions import TruncDate
步骤2:修改ModelAnswer的唯一约束
把原来的字段约束改成基于日期表达式的约束,完整代码如下:
class ModelAnswer(BaseModel): questions = models.ForeignKey( to=ModelQuestions, on_delete=models.CASCADE ) answer = models.TextField() user = models.ForeignKey(User, on_delete=models.CASCADE) def __str__(self): return f'{self.questions} - by {self.user}' class Meta: constraints = [ models.UniqueConstraint( expressions=[ TruncDate('created_at'), # 提取created_at的纯日期部分 'user', 'questions' ], name='unique_daily_answer_per_user_per_question' ) ]
原理说明
TruncDate('created_at')会把created_at(datetime类型)转换成YYYY-MM-DD格式的纯日期值,同一用户在同一天对同一问题提交的所有答案,这个日期值完全相同,唯一约束就会直接阻止重复提交。到了第二天,日期值更新,用户就能再次提交该问题的答案。
注意事项
- 确保你的
BaseModel中已经定义了created_at字段(比如created_at = models.DateTimeField(auto_now_add=True)),如果没有需要手动添加。 - 修改模型后必须执行数据库迁移:
python manage.py makemigrations python manage.py migrate
内容的提问来源于stack exchange,提问作者lord stock
相关产品推荐
相关产品推荐

