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

Django 2.1.15自定义排序:点赞数与时间差算法实现求助

Django Review模型自定义评分排序解决方案

嘿,我来帮你搞定这个自定义排序的问题!先梳理下你的场景:

环境信息

  • Django版本:2.1.15
  • Python版本:3.7.4
  • 配置:settings.py中LANGUAGE_CODE='ko-kr',TIME_ZONE='Asia/Seoul'
  • Review模型字段:title、content、movie外键、user外键、like_users多对多字段、created_at和updated_at时间字段

需求

需要按公式 Count(like_users)/(当前时间与created_at的分钟差+60) 降序排序,其中时间差需转为整数分钟。

原代码的问题

你之前的尝试有几个关键问题:

  1. 直接给DurationField类型的时间差加整数60——时间间隔和整数不能直接运算,类型不匹配
  2. 没有计算like_users的总数量,缺少公式里的分子
  3. 没有正确计算总分钟差(只算了分钟部分,忽略了小时/天等更长的时间单位)

正确实现代码

from django.db.models import Count, F, ExpressionWrapper, Value
from django.db.models.fields import IntegerField, DateTimeField, FloatField, DurationField
from django.db.models.functions import ExtractHour, ExtractMinute
from django.utils import timezone

def test(request):
    now = timezone.localtime()
    
    # 分步计算自定义评分并排序
    reviews = Review.objects.annotate(
        # 1. 计算当前时间与created_at的时间差(时间间隔类型)
        time_diff=ExpressionWrapper(
            Value(now, output_field=DateTimeField()) - F('created_at'),
            output_field=DurationField()
        ),
        # 2. 从时间差中提取小时和分钟,计算总分钟数
        diff_hours=ExtractHour('time_diff'),
        diff_minutes=ExtractMinute('time_diff'),
        total_minutes=ExpressionWrapper(
            F('diff_hours') * 60 + F('diff_minutes'),
            output_field=IntegerField()
        ),
        # 3. 计算公式的分母:总分钟差 + 60
        denominator=ExpressionWrapper(
            F('total_minutes') + 60,
            output_field=IntegerField()
        ),
        # 4. 计算like_users的总数(分子)
        like_count=Count('like_users'),
        # 5. 计算最终评分
        score=ExpressionWrapper(
            F('like_count') / F('denominator'),
            output_field=FloatField()
        )
    ).order_by('-score')  # 按评分降序排序

    # 如果需要获取字典形式的数据,可添加.values()
    # review_data = reviews.values()
    
    # 后续逻辑:比如传递给模板渲染
    return render(request, 'your_template.html', {'reviews': reviews})

关键说明

  1. 时间差计算:通过ExtractHour和ExtractMinute提取时间差的小时和分钟,转换成总分钟数,避免忽略长于1小时的时间间隔
  2. 类型匹配:所有运算都用ExpressionWrapper指定输出字段类型,确保数据库层面的运算不会出现类型错误
  3. 评分计算:先分别算出分子(点赞数)和分母(总分钟差+60),再做除法得到最终评分,最后按-score降序排序

内容的提问来源于stack exchange,提问作者mmm lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:07:52