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

Django好友请求accept方法报FriendList查询不存在错误

问题背景

已完成好友列表、好友请求模块的数据模型定义,在FriendRequest类中实现业务方法:调用accept方法时,将请求双方的User关联关系写入对应FriendList记录。实际运行时抛出查询不存在的异常,已实现好友关联添加逻辑,无法定位错误来源。

业务代码

views.py

friend_request = FriendRequest.objects.get(id=request_id)

if request_option == 'accept':
  friend_request.accept()
if request_option == 'decline':
  friend_request.decline()

models.py

class FriendList(models.Model):
    user    = models.OneToOneField(User, on_delete=models.CASCADE, related_name="user")
    friends = models.ManyToManyField(User, blank=True, related_name="friends") 

    def add_friend(self, account):
        if not account in self.friends.all():
            self.friends.add(account)
            self.save()


class FriendRequest(models.Model):
    sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name="sender")
    receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name="receiver")
    is_active = models.BooleanField(blank=False, null=False, default=True)
    timestamp = models.DateTimeField(auto_now_add=True)

    def accept(self):
        receiver_friend_list = FriendList.objects.get(user=self.receiver)
        if receiver_friend_list:
            receiver_friend_list.add_friend(self.sender)
            sender_friend_list = FriendList.objects.get(user=self.sender)
            if sender_friend_list:
                sender_friend_list.add_friend(self.receiver)
                self.is_active = False
                self.save()

    def decline(self):
        self.is_active = False
        self.save()
报错栈
File "C:\Users\models.py", line 77, in accept
    receiver_friend_list = FriendList.objects.get(user=self.receiver)
  File "C:\Python310\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Python310\lib\site-packages\django\db\models\query.py", line 496, in get
    raise self.model.DoesNotExist(
friends.models.FriendList.DoesNotExist: FriendList matching query does not exist.
错误原因
  • 核心问题:FriendList与User是一对一关联,没有实现「用户创建时自动生成对应FriendList记录」的逻辑,新注册用户不存在绑定的FriendList数据。
  • 逻辑漏洞:FriendList.objects.get()查询不到匹配数据时会直接抛出DoesNotExist异常,不会返回空值,代码中写的if receiver_friend_list:判断完全不会执行,异常会在查询时直接触发。
  • 潜在隐患:当前模型的related_name配置存在命名冲突,FriendList.user字段的反向关联名和字段本身重名,后续做反向查询时会出现属性覆盖问题。
修复方案
  • 方案一:通过Django信号机制,在用户创建时自动生成对应的好友列表记录,从根源避免查询不到的问题:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import User

@receiver(post_save, sender=User)
def init_user_friend_list(sender, instance, created, **kwargs):
    if created:
        FriendList.objects.create(user=instance)
  • 方案二:修改accept方法的查询逻辑,查询不到好友列表时自动创建,替代会直接抛错的get()调用:
def accept(self):
    # 查无记录时自动创建接收方好友列表
    receiver_friend_list, _ = FriendList.objects.get_or_create(user=self.receiver)
    receiver_friend_list.add_friend(self.sender)
    # 查无记录时自动创建发送方好友列表
    sender_friend_list, _ = FriendList.objects.get_or_create(user=self.sender)
    sender_friend_list.add_friend(self.receiver)
    self.is_active = False
    self.save()
  • 可选优化:调整related_name命名避免冲突,比如将FriendList.user的related_name改为friend_list,friends字段的related_name改为friend_relations,语义更清晰也不会出现命名覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:33:06