Home > Software engineering >  Django get objects created by users, with those users belonging to a list of users
Django get objects created by users, with those users belonging to a list of users

Time:01-08

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 Users. 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.

  • Related