使用drf_multiple_model获取粉丝帖子和问题时遇QuerySet类型错误
问题:DRF多模型视图筛选粉丝动态时出现QuerySet类型错误
我定义了如下Follow模型用于记录用户关注关系:
class Follow(models.Model): followee = models.ForeignKey(User, on_delete=models.CASCADE, related_name="followee") follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follower") created_at = models.DateTimeField(auto_now_add=True, verbose_name="created at") updated_at = models.DateTimeField(auto_now=True, verbose_name="updated at") class Meta: unique_together = ["followee", "follower"] def __str__(self): return "{} is following {}".format(self.follower, self.followee) def save(self, *args, **kwargs): if self.followee == self.follower: return "You cannot follow yourself" else: super().save(*args, **kwargs)
用户可发布Post和Question类型内容,我希望展示关注特定用户的所有粉丝发布的帖子和问题(简化为展示关注我的用户的动态)。使用drf_multiple_model模块编写视图时,出现错误:
Cannot use QuerySet for "Follow": Use a QuerySet for "User".
视图代码:
def get_followers(queryset, request, *args, **kwargs): id = kwargs['user'] user = User.objects.get(id=id) followers = Follow.objects.all().filter(followee=user) return queryset.filter(user__in=followers) class HomeView(FlatMultipleModelAPIView): permission_classes = [IsAuthenticated] def get_querylist(self): querylist = [ {'queryset':Post.objects.all(), 'serializer_class': UserPostSerializer, 'filter_fn': get_followers, 'label':'post'}, {'queryset':Question.objects.all(), 'serializer_class': QuestionSerializer, 'filter_fn': get_followers, 'label':'question'}, ] return querylist
请问我哪里出错了?
错误原因与修复方案
核心错误原因
get_followers函数中,followers是Follow模型的QuerySet,但queryset.filter(user__in=followers)需要传入的是User模型的QuerySet/用户ID列表——因为Post和Question都是通过user字段关联User模型的,无法直接用Follow对象集合去筛选。
修复步骤
修改get_followers函数,获取粉丝对应的User对象或ID列表,再用于筛选Post/Question:
方式一:利用反向关联直接查询粉丝用户
通过Django ORM的双下划线查询,直接获取关注目标用户的所有粉丝:
def get_followers(queryset, request, *args, **kwargs): user_id = kwargs['user'] # 查询所有关注该用户的粉丝用户 follower_users = User.objects.filter(follower__followee_id=user_id) return queryset.filter(user__in=follower_users)
方式二:提取粉丝ID列表(性能更优)
从Follow表中直接提取粉丝用户的ID,再用ID列表筛选:
def get_followers(queryset, request, *args, **kwargs): user_id = kwargs['user'] # 获取所有粉丝的ID列表 follower_ids = Follow.objects.filter(followee_id=user_id).values_list('follower_id', flat=True) return queryset.filter(user_id__in=follower_ids)
额外优化:修正Follow模型的save方法
原Follow模型的save方法返回字符串无法阻止"关注自己"的操作,应该抛出ValidationError来终止保存:
from django.core.exceptions import ValidationError class Follow(models.Model): # ... 其他字段不变 ... def save(self, *args, **kwargs): if self.followee == self.follower: raise ValidationError("You cannot follow yourself") super().save(*args, **kwargs)
内容的提问来源于stack exchange,提问作者crawlingdev
相关产品推荐
相关产品推荐

