Django中如何为模型添加约束避免用户关注自身的非法操作
解答
Django完全支持添加这类约束,你可以同时添加数据库层面校验和模型运行时校验两层保障,另外先纠正你现有模型的两个不合理之处:
- 当前
followee_id用OneToOneField不符合业务逻辑:一个用户可以被多个用户关注,OneToOneField会限制同一个用户只能被1个人关注,建议改为ForeignKey - 字段命名冗余:Django的
ForeignKey会自动在数据库字段末尾添加_id后缀,你当前命名为follower_id的话,最终数据库字段会变成follower_id_id,建议直接命名为follower、followee即可,代码中依然可以通过xxx.follower_id直接获取关联用户的ID值
修改后完整模型代码
from django.db import models from django.core.exceptions import ValidationError from django.db.models import Q class FollowUser(AbstractSimpleModel): follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following') followee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='followers') class Meta: constraints = [ # 数据库层面禁止自己关注自己的约束 models.CheckConstraint( check=~Q(follower=models.F('followee')), name='cannot_follow_self' ), # 额外添加联合唯一约束,避免重复关注同一个用户,可按需保留或删除 models.UniqueConstraint( fields=['follower', 'followee'], name='unique_follow_relation' ) ] def clean(self): # 模型运行时校验,保存前触发 if self.follower == self.followee: raise ValidationError('用户不能关注自身') def save(self, *args, **kwargs): # 自动触发校验,不需要手动调用full_clean self.full_clean() super().save(*args, **kwargs)
约束说明
- 数据库层
CheckConstraint:兼容性最高,即使绕过Django ORM直接操作数据库也会触发约束报错,支持Django 2.2及以上版本 - 模型
clean方法校验:会在调用full_clean()时触发,报错信息更友好,适合表单、Admin等场景的错误提示 - 额外新增的
UniqueConstraint可以避免同一个用户重复关注另一个用户,属于关注业务的常见通用约束,你可以根据需求选择是否添加
内容的提问来源于stack exchange,提问作者user12314098
相关产品推荐
相关产品推荐

