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

Django好友关系模型获取好友异常:返回当前用户而非实际好友

修复双向好友列表获取逻辑(排除自身)

问题根源

当前get_friends函数的列表推导式逻辑错误:不管当前用户处于Friendship记录的user还是friend字段,都统一取f.user,导致当当前用户是记录的user时,会把自己加入好友列表,最终返回结果包含自身而非正确好友。

修复后的代码

def get_friends(queryset, request, *args, **kwargs):
    user_id = kwargs['user']
    user = User.objects.get(id=user_id)
    # 筛选所有和当前用户相关的好友关系记录
    friendship_records = Friendship.objects.filter(Q(user=user) | Q(friend=user))
    # 遍历记录,根据当前用户所在字段取对应的好友
    friends = []
    for record in friendship_records:
        if record.user == user:
            friends.append(record.friend)
        else:
            friends.append(record.user)
    # 双重保障:排除自身(逻辑上不会出现,但避免异常数据)
    friends = [friend for friend in friends if friend != user]
    # 返回过滤后的queryset
    return queryset.filter(user__in=friends)

优化说明

  1. 逻辑修正:通过判断当前用户在Friendship记录中的位置,精准提取对应的好友对象
  2. 变量名规范:将id改为user_id,避免与内置函数命名冲突
  3. 异常防护:增加自身排除逻辑,即使出现异常数据也能保证结果正确性

可选ORM优化(减少内存遍历)

如果希望直接通过数据库查询完成逻辑,避免内存遍历,可以用Django ORM的Case/When语法:

from django.db.models import Case, When, IntegerField

def get_friends(queryset, request, *args, **kwargs):
    user_id = kwargs['user']
    # 直接从数据库层面计算好友ID
    friend_ids = Friendship.objects.filter(
        Q(user=user_id) | Q(friend=user_id)
    ).annotate(
        friend_id=Case(
            When(user=user_id, then='friend_id'),
            When(friend=user_id, then='user_id'),
            output_field=IntegerField()
        )
    ).values_list('friend_id', flat=True).distinct()
    # 排除自身ID
    friend_ids = [fid for fid in friend_ids if fid != user_id]
    return queryset.filter(user__in=friend_ids)

内容的提问来源于stack exchange,提问作者crawlingdev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:04:01