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

Django中post_save信号实现双向关注自动加好友问题求助

问题分析与修正方案

原代码的核心问题

  1. 查询逻辑重复且判断错误:你写的两个filter本质是同一个查询(仅参数顺序调换),而且用str(instance.Follower)和QuerySet转字符串做比较完全不成立——QuerySet转字符串是类似<QuerySet [<Follow: Follow object (1)>]>的格式,永远不可能和用户对象的字符串相等。
  2. 缩进错误:Python是缩进敏感语言,你信号函数里if created:下面的代码缩进不规范,会导致逻辑根本无法执行。
  3. 字段名不规范:Followe拼写应为Followee(被关注者),虽不影响功能,但可读性极差。

修正后的完整代码

from django.db import models
from django.contrib.auth.models import User
from django.utils.timezone import now
from django.db.models.signals import post_save
from django.dispatch import receiver

class Follow(models.Model):
    # 修正字段名拼写,符合Python命名规范
    follower = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        related_name='following',  # 关联名优化:用户关注的人
        blank=True
    )
    followee = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        related_name='followers',  # 关联名优化:关注用户的人
        blank=True
    )
    created = models.DateTimeField(default=now)

    class Meta:
        # 禁止同一用户重复关注同一对象
        unique_together = ('follower', 'followee')

@receiver(post_save, sender=Follow)    
def create_friend(sender, instance, created, **kwargs):
    # 仅处理新创建的关注记录
    if created:
        # 检查被关注者是否已反向关注当前用户(即互相关注)
        is_mutual_follow = Follow.objects.filter(
            follower=instance.followee, 
            followee=instance.follower
        ).exists()
        
        if is_mutual_follow:
            # 自动创建/更新好友关系,避免重复创建
            Friends.objects.update_or_create(
                from_user=instance.follower, 
                to_user=instance.followee
            )
            # 若需要双向好友记录,可取消下方注释
            # Friends.objects.update_or_create(
            #     from_user=instance.followee, 
            #     to_user=instance.follower
            # )
    # 更新操作无需处理,直接跳过
    else:
        pass

class Friends(models.Model):
    from_user = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        related_name='friends',  # 关联名优化:用户的好友列表
        blank=True
    )
    to_user = models.ForeignKey(
        User, 
        on_delete=models.SET_NULL, 
        null=True, 
        related_name='friend_of',  # 关联名优化:谁把该用户加为好友
        blank=True
    )
    created = models.DateTimeField(default=now)

    class Meta:
        # 禁止同一对好友重复创建记录
        unique_together = ('from_user', 'to_user')

关键修正说明

  1. 查询逻辑优化:用exists()判断反向关注记录是否存在,这是Django中判断记录存在的高效方式,无需取出整个QuerySet。
  2. 缩进规范修正:调整if created:下方代码的缩进,确保逻辑能正常执行。
  3. 字段与关联名优化:将字段名改为小写(符合Python命名规范),同时优化related_name,方便后续查询操作。
  4. 添加唯一约束:在Follow和Friends模型的Meta类中添加unique_together,避免无效重复数据。
  5. 异常处理调整:移除原代码中吞掉错误的try-except(建议替换为日志打印),否则出现问题无法定位原因。

内容的提问来源于stack exchange,提问作者Harshith Kumara Kannan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:01:15