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

Django Rest Framework如何按模型自定义property属性blog_views实现排序

实现方案

你当前定义的blog_views是Python层面的计算属性,数据库无法直接识别用于排序,最优实现分两种场景,可按需选择:

方案一:无需修改模型,用annotate聚合(适合中小流量站点)

该方案无需改动模型结构,直接在视图层通过数据库聚合实现排序,同时能解决原属性带来的N+1查询问题。

步骤1:修改视图代码

首先导入Django的聚合函数Count,重写视图查询集,新增ordering_fields允许按浏览量排序:

from django.db.models import Count

class PostList(generics.ListCreateAPIView):
    """Blog post lists"""
    # 聚合统计关联的address_views数量,生成可用于排序的blog_views字段
    queryset = Post.objects.annotate(
        blog_views=Count('address_views', distinct=True)
    ).all()
    serializer_class = serializers.PostSerializer
    authentication_classes = (JWTAuthentication,)
    permission_classes = (PostsProtectOrReadOnly, IsMentorOnly)
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['title', 'body',
                     'tags__name', 'owner__email',
                     'owner__username'
                     ]
    # 新增允许排序的字段,包含我们聚合出来的blog_views
    ordering_fields = ['created', 'title', 'blog_views']

步骤2:可选优化

因为现在查询集已经通过聚合提前算出了每个Post的浏览量,原Python层面的blog_views property可以直接删除,既避免属性命名冲突,也能解决原来每次调用property都会触发一次数据库查询的N+1问题。

使用方式

启动服务后直接在URL加排序参数即可:

  • 按浏览量从低到高排序:接口地址?ordering=blog_views
  • 按浏览量从高到低排序:接口地址?ordering=-blog_views

方案二:新增缓存字段(适合高流量站点,性能最优)

如果站点访问量较大,每次请求都做聚合统计会给数据库带来明显压力,可以在模型中新增一个实际存储浏览量的字段,每次有新的访问时直接更新该字段,排序时直接走普通字段索引,性能最高。

步骤1:修改模型新增字段

class Post(TimeStampedModel, models.Model):
    # 原有字段保持不变
    blog_views = models.IntegerField(_("浏览量"), default=0, db_index=True) # 加索引提升排序性能

    # 原有的@property blog_views直接删除

执行makemigrations和migrate将字段同步到数据库。

步骤2:更新访问计数逻辑

在原有新增访问记录(往address_views添加IP)的逻辑里,同步加上post.blog_views +=1的更新逻辑即可。

步骤3:修改视图配置

不需要再做annotate操作,直接把blog_views加入ordering_fields即可:

class PostList(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    # 其他配置保持不变
    ordering_fields = ['created', 'title', 'blog_views']

内容的提问来源于stack exchange,提问作者Lutaaya Huzaifah Idris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:06:03