You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改DRF的Post序列化器以添加点赞计数字段?

解决DRF Post序列化器添加点赞计数的问题

下面提供三种可行的实现方式,按需选择:

方案一:用SerializerMethodField快速实现

直接在序列化器中新增like_count字段,通过SerializerMethodField调用自定义方法统计点赞数:

修改后的序列化器代码:

class PostSerializers(serializers.ModelSerializer):
    user = UserSerializer(required=False)
    # 定义点赞计数字段
    like_count = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = ['id', 'title', 'link', 'user', 'descripotion', 'like_count']
        read_only_fields = ['id']

    def get_like_count(self, obj):
        # 统计当前Post关联的Like记录总数
        return obj.like_set.count()

说明:因为Like模型的外键指向Post,Django会自动生成反向关联的like_set属性,通过它可以获取当前Post的所有点赞记录,再调用count()得到数量。

方案二:在模型中添加属性(提升复用性)

如果项目多个地方需要用到点赞计数,可以在Post模型里新增一个属性方法,这样序列化器和其他场景都能直接使用:

先修改Post模型:

class Post(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    title = models.CharField(max_length=255)
    descripotion = models.TextField(blank=True)
    link = models.CharField(max_length=255, blank=True)

    def __str__(self):
        return self.title
    
    @property
    def like_count(self):
        return self.like_set.count()

然后更新序列化器,只需把like_count加入字段列表:

class PostSerializers(serializers.ModelSerializer):
    user = UserSerializer(required=False)

    class Meta:
        model = Post
        fields = ['id', 'title', 'link', 'user', 'descripotion', 'like_count']
        read_only_fields = ['id']

方案三:用annotate优化查询(避免N+1性能问题)

前两种方法在查询多个Post时,会触发每条Post单独查询点赞数的N+1数据库请求,性能不佳。推荐在视图中用annotate提前批量计算点赞数:

比如在列表视图中:

from django.db.models import Count

class PostListView(generics.ListAPIView):
    serializer_class = PostSerializers
    # 用annotate批量计算每个Post的点赞数,一次性完成查询
    queryset = Post.objects.all().annotate(like_count=Count('like'))

然后序列化器中直接添加like_count字段即可:

class PostSerializers(serializers.ModelSerializer):
    user = UserSerializer(required=False)
    # 标记为只读,因为值由annotate提供
    like_count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'link', 'user', 'descripotion', 'like_count']
        read_only_fields = ['id']

这种方法只需要一次数据库查询,性能更优,适合列表查询场景。

内容的提问来源于stack exchange,提问作者django developer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:50:45