如何修改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
相关产品推荐
相关产品推荐

