I am trying to build a small social network where users can like posts. I am using Django 3.1.7. I have defined my model for the post as follows:
class Post(models.Model):
date_published = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.CharField(max_length=240, blank=False, default=None)
user_like = models.ManyToManyField(User, blank=True, related_name='likes')
def __str__(self):
return f'{self.user.username} posted \"{self.content}\" on {self.date_published}'
From my views.py
I want to return the posts with an annotation of whether the current user has liked a given post. I am trying as follows:
def index(request):
posts = Post.objects.all().annotate(
likes=Count('user_like')).order_by('-date_published')
if request.user.is_authenticated:
posts = Post.objects.all().annotate(
likes=Count('user_like'), liked=request.user in 'user_like'.all).order_by('-date_published')
paginator = Paginator(posts, 10)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, "network/index.html", {
'post_form': PostForm(),
'page_obj': page_obj
})
But unfortunately, I can not make the query work. I assume that the part where I check if the user is in the relationship is wrong ( liked=request.user in 'user_like'.all
) as it is treating 'user_like'
as str
and not as the field in the Post.
How should I annotate the posts to include whether the user has liked them or not based on the ManyToManyField
between them? Thanks
You can work with an Exists
subquery [Django-doc] :
from django.db.models import Exists, OuterRef
posts = Post.objects.annotate(
likes=Count('user_like'),
liked=Post.user_like.through.objects.filter(
post_id=OuterRef('pk'),
user_id=request.user.pk
)
).order_by('-date_published')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.