Показывать количество лайков в каждом посте django REST API
models.py
class Post(models.Model):
title = models.CharField(max_length=150)
class PostLike(models.Model):
like = models.CharField(max_length=20)
user = models.ForeignKey(User,on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
Serializer.py
class PostSerializer(serializers.ModelSerializer):
likes = serializers.SerializerMethodField("like_count")
class Meta:
model = Post
fields = ("__all__")
def like_count(self,obj):
total_like = self.context.get("like_count")
return total_like
views.py
@api_view(["POST"])
def allpost(request):
id = request.data
post_list = Post.objects.all()
like_count = PostLike.objects.filter(post_id = id ).count()
post_serializer = PostSerializer(post_list,many=True,context={"like_count":like_count})
return Response(request,post_serializer.data)
urls.py
urlpatterns = [
path('post/',views.allpost,name="post"),
]
вывод:
[
{
"id": 1,
"likes": 1,
"title": "post 1",
},
{
"id": 2,
"likes": 1,
"title": "post 2",
},
{
"id": 3,
"likes": 1,
"title": "post 3",
},
]
db
id like post_id user_id
1 1 1 1
2 1 2 1
3 1 1 2
Фактически в моей базе данных лайки есть: пост 1 имеет 2 лайка пост 2 имеет 1 лайк пост 3 не имеет ни одного лайка
Я хочу показать это вот так. но он показывает лайки первого поста для каждого поста. как я могу это исправить? Я знаю, что проблема в like_count в view. но я не знаю, что поставить вместо id .
извините за мой плохой английский Заранее спасибо
Вы можете сделать свой сериализатор следующим образом:
class PostSerializer(serializers.ModelSerializer):
likes = serializers.SerializerMethodField()
class Meta:
model = Post
fields = ("__all__")
def like_count(self, obj):
total_like = PostLike.objects.filter(post_id=obj.id).count()
return total_like
views.py было бы
@api_view(["POST"])
def allpost(request):
post_list = Post.objects.all()
post_serializer = PostSerializer(post_list, many=True)
return Response(request, post_serializer.data)
Используйте отношения, это очень помогает. Определите функцию в модели Post, чтобы сериализатор мог легко ее получить.
models.py:
class Post(models.Model):
title = models.CharField(max_length=150)
def likes_count(self):
return self.likes.all().count()
class PostLike(models.Model):
like = models.CharField(max_length=20)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='post_likes')
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='likes')
serializers.py:
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ["id", "title", "likes_count"]
# That part you can delete
# def like_count(self,obj):
# total_like = self.context.get("like_count")
# return total_like
views.py:
@api_view(["POST"])
def allpost(request):
post_list = Post.objects.all()
post_serializer = PostSerializer(post_list, many=True)
return Response(request, post_serializer.data)
Как работают отношения:
Мы добавили related_name='likes' к полю PostLike.post. Это поле является связью как ForeignKey с объектом Post, на который оно ссылается. Это означает, что это своего рода ярлык, который вы можете использовать обратным образом. В основном он ведет себя как классический QuerySet, но только со связанными объектами (в данном случае PostLikes объектами, которые имеют данный Post объект.
Давайте воспользуемся приведенными выше моделями. Примеры использования:
post = Post.objects.first() # now 'post' is the first Post object
post.likes # it's just a relationship object, not helpful for now
post.likes.all() # that gives QuerySet of all PostLike objects, that has this instance of Post as ForeignKey.
post.likes.filter(user__id=1) # that gives filtered QuerySet of PostLike with this instance of Post and instance of User with id 1
post.likes.last() # that gives related PostLike object with highest pk/id - depending on ordering of course
post.likes.all().count() # that gives the total count of all related objects
Читайте официальную документацию, это действительно полезно. https://docs.djangoproject.com/en/4.0/topics/db/models/#relationships