I have a model for followers. Here is the model:
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)
Users create multiple types of objects like posts and questions. I would like to show all the posts and questions of all the users that follow a specific user. Simplified show me all the posts and questions of users that follow me.
I am using a module called drf_multiple_model
and here is my view, which I cannot get to work. It gives me the following error that I don't understand:
Cannot use QuerySet for "Follow": Use a QuerySet for "User".
Here is the view I am using:
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
What am I doing wrong please?
CodePudding user response:
In order to be able to use the __in
filter the followers
should be an iterable of User
s. Try this:
followers = [f.follower for f in Follow.objects.filter(followee=user)]
or
followers = [f.follower for f in user.follower.all()]
CodePudding user response:
You can filter with a JOIN, like:
def get_followers(queryset, request, *args, **kwargs):
return queryset.filter(user__follower__followee_id=kwargs['user'])
This will fetch the items in a single query, and thus avoid first querying the followers and then obtain the items.