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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 03:51:03