Показывать количество лайков в каждом посте 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

Вернуться на верх