Super
Super

Reputation: 15

Filtering one model based on another model's field

I have the following models:

class User(AbstractUser):
    pass

class Post(models.Model):
    post_user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_content = models.TextField()
    post_date = models.DateTimeField(default=timezone.now)

class Follow(models.Model):
    follow_user = models.ForeignKey(User, on_delete=models.CASCADE)
    follow_target = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follow_target')

I'm trying to create a queryset of all posts that were created by users I follow (me being the currently logged in user). My queryset currently looks like this but I keep getting NameError: field not found:

postresult = Post.objects.all().filter(post_user=follow__follow_target, follow__follow_user=request.user)

Any help will be greatly appreciated!

Upvotes: 1

Views: 1323

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

You filter with:

postresult = Post.objects.filter(
    post_user__follow_target__follow_user=request.user
)

The post_user will follow the ForeignKey from Post to User. Then we use the related_name='follow_target' to follow the relation to the Follow object, and then we use follow_user to retrieve the following user.


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: The related_name=… parameter [Django-doc] is the name of the relation in reverse, so from the User model to the Follow model in this case. Therefore it (often) makes not much sense to name it the same as the forward relation. You thus might want to consider renaming the follow_target relation to followers.

In case you rename the related name, the query is thus:

postresult = Post.objects.filter(
    post_user__followers__follow_user=request.user
)

Upvotes: 2

Related Questions