首页 > 解决方案 > 如何在 DRF 中使用多对多直通模型

问题描述

所以我正在尝试使用 Django 和 REST 框架以及 React 中的前端在社交媒体网站中实现一般的“点赞”功能。使用Post模型保存所有帖子,我有一个多对多字段用于存储喜欢并创建了一个直通模型,如下所示:

class PostLike(models.Model):
    user = models.ForeignKey(AppUser, on_delete=models.CASCADE)
    post = models.ForeignKey("Post", on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)


class Post(models.Model):
    user = models.ForeignKey(AppUser, on_delete=models.CASCADE)
    caption = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    edited_at = models.DateTimeField(auto_now=True)
    likes = models.ManyToManyField(
        AppUser, related_name="post_user", blank=True, through=PostLike
    )

AppUser 是使用的自定义身份验证模型

同样,我为上述模型创建了序列化程序和视图集:

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = "__all__"


class PostLikeSerializer(serializers.ModelSerializer):
    class Meta:
        model = PostLike
        fields = "__all__"

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer


class PostLikeViewSet(viewsets.ModelViewSet):
    queryset = PostLike.objects.all()
    serializer_class = PostLikeSerializer

我的问题是,我如何使用 API 调用从帖子中“点赞”或删除现有的“点赞”?我知道的一种方法是使用用户 PK 和 post PK 向PostLike端点发出 POST 请求以创建 PostLike 实例,但我不知道使用相同方法“删除”类似的方法。请帮忙!

标签: pythondjangodjango-rest-framework

解决方案


你可以使用APIView而不是ViewSet这样:

from rest_framework import views

class PostLikeApiView(views.APIView):
    serializer = PostLikeSerializer(data=request.data)

    if serializer.is_valid():
        user = serializer.data['user']
        post = serializer.data['post']
    
        post_like_obj = PostLike.objects.filter(user=user, post=post)
        if post_like_obj.exists():
            post_like_obj.delete()
            result = 'unliked'
        else:
            PostLike.objects.create(user=user, post=post)
            result = 'liked'
            
        return Response(
            {
                'result': result,
            },
            status=status.HTTP_200_OK
        )
            
    else:
        return Response(
            serializer.errors,
            status=status.HTTP_400_BAD_REQUEST
        )

推荐阅读