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
相关产品推荐
相关产品推荐

