Django用户关注系统:判断登录用户是否关注目标用户功能异常排查
看起来你在用户关注状态判断这块踩了两个常见的坑,我来帮你一步步梳理解决:
首先先明确你的场景:你的系统用FollowLog记录关注操作(关注设status=following,取消关注改status=unfollowed不删记录),但在CustomUserDetailsSerializer的get_am_i_following方法里,判断登录用户是否关注目标用户时出了问题:
- 用
filter(slug=user.slug)直接报错"Cannot resolve keyword 'slug' into field"; - 换成
filter(pk=user.pk)后,明明已经关注了目标用户,却返回False。
第一个问题:为啥用slug过滤会报错?
这个错误其实很直白:你的FollowLog模型里根本没定义slug字段!你错误地把目标用户的slug当成了FollowLog的字段来过滤,当然找不到。FollowLog是通过外键关联用户的(比如follower存关注者,followed存被关注者),你得通过这些外键关联的字段去查询,不能直接用用户的slug。
第二个问题:用pk过滤为啥返回错误结果?
就算换成了pk=user.pk,你的查询条件还是不完整啊!想想你的业务逻辑:
- 你需要确认当前登录用户是关注者,
- 目标用户是被关注者,
- 而且这条
FollowLog的status必须是following(毕竟取消关注只是改状态,不是删记录)。
如果只过滤目标用户的pk,相当于查所有关注过这个用户的记录,但没限定是当前登录用户,也没限定状态是有效的关注,结果自然不对。
具体修复步骤
第一步:先确认你的FollowLog模型结构
假设你的FollowLog是类似这样的(如果字段名不一样,对应调整就行):
class FollowLog(models.Model): follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following_logs') followed = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower_logs') status = models.CharField(max_length=20, choices=[('following', 'Following'), ('unfollowed', 'Unfollowed')]) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
第二步:修复get_am_i_following方法
把你的方法改成下面这样,确保查询条件完整:
def get_am_i_following(self, obj): request = self.context.get('request') # 先处理未登录的情况 if not request or not request.user.is_authenticated: return False current_user = request.user target_user = obj # obj就是当前查询的目标用户 # 先判断是不是查自己 if current_user.pk == target_user.pk: return 'Myself' try: # 关键:同时过滤三个条件! is_following = FollowLog.objects.filter( follower=current_user, followed=target_user, status='following' ).exists() return is_following # 存在就返回True,否则False except Exception as e: # 这里可以加日志记录异常,暂时返回你定义的异常标识 return 'not following'
第三步:别忘了把request传入序列化器的context
在你的UserRetriveAPIView里,要确保序列化器能拿到当前请求,不然拿不到登录用户:
class UserRetriveAPIView(RetrieveAPIView): serializer_class = CustomUserDetailsSerializer queryset = User.objects.all() def get_serializer_context(self): context = super().get_serializer_context() # 把request放进context里 context['request'] = self.request return context
额外要验证的点
你说查询目标用户的followers能看到登录用户,那可以手动查一下对应的FollowLog记录,确认它的status确实是following——有时候可能创建关注记录时没把status设对,或者取消关注后又改回来了但没生效,这些细节也会导致判断错误。
总结
核心问题就是你的查询条件不完整:既没关联FollowLog的用户外键,也没限定有效的关注状态。按照上面的步骤调整后,应该就能正确返回登录用户对目标用户的关注状态了。
内容的提问来源于stack exchange,提问作者Opeyemi Odedeyi

