使用Django CheckConstraint限制单Discussion关联Message数量
Django 4.1中使用CheckConstraint限制关联消息数量的问题
背景与问题
我正在使用Django 4.1和PostgreSQL,根据官方文档,CheckConstraint支持Q对象和Expression,于是编写代码尝试限制每个Discussion关联的Message数量,但执行makemigrations时无任何反应(Count继承自Func)。
我了解到可以在ForeignKey字段使用validators方案,但该方案不够健壮,希望仅使用Django原生方案,无需创建SQL函数。
代码实现
from django.core.exceptions import ValidationError from django.db import models from django.db.models.lookups import IntegerLessThan class Discussion(models.Model): MAX_MESSAGES = 10 class Message(models.Model): discussion = models.ForeignKey( "discussion.Discussion", models.CASCADE, related_name="messages", ) constraints = [ models.CheckConstraint( name="limit_discussion_messages", check=IntegerLessThan( models.Count("discussion", filter=models.Q(discussion=models.F("discussion"))), models.Value(Discussion.MAX_MESSAGES), ), ), ]
后续结论
经过讨论及查阅相关解答后发现:在Django 4.1版本中,不使用原生SQL无法实现无数据竞态的完美约束。
若仅依赖Django的验证系统,有两种可选方案:
- 保存前检查:需接受可能存在少量超出限制的记录
- 保存后检查:需接受可能回滚过多操作,但能确保限制被严格执行
内容的提问来源于stack exchange,提问作者Barbeuk
相关产品推荐
相关产品推荐

