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

Django标注DateTime字段属性报错:无法将关键字'toordinal'解析为字段

帖子评分系统时间窗口排序实现问题

我正在开发网站帖子评分系统,排序逻辑会关联评论、浏览量、表情反应等关联字段,让结果排序更具参考性。
但首页不适合展示热度高但过于陈旧的帖子,因此我决定将帖子创建时间纳入排序规则。
问题在于DateTime类型的时间精度过高,如果直接按该字段排序会完全忽略评分规则的作用,最终只会返回纯时间顺序的信息流。

测试解决方案时,我尝试使用toordinal内置函数得到代表公元1年1月1日至今天数的数值,计划将该值与发帖小时、post_minute // 14的结果拼接,以此实现每14分钟为一个时间窗口,窗口内所有帖子完全按评分排序,该方案效果理想且调整灵活。
我参考相关资料后,尝试在F表达式中通过双下划线访问该属性,代码如下:

posts = Post.objects.all().annotate(
            score=((F("view_count")/20) + (Count("post_emojis")/10) + (Count("post_comments")/5)),
            ordinal_time=(F('created_at__toordinal'))
        )        

运行后返回如下错误:

Cannot resolve keyword 'toordinal' into field. Join on 'created_at' not permitted.

这是我第一次使用annotate功能,目前暂时不知道如何解决该问题。


编辑补充

我已经找到可行方案了,等后续测试确认不会导致查询速度过慢后我会将其作为答案发布,目前实现代码如下:

posts = Post.objects.all().annotate(
            score=((F("view_count")/20) + (Count("post_emojis")/10) + (Count("post_comments")/5)),
            year=(Extract(expression="created_at", lookup_name='year')),
            month=(Extract(expression="created_at", lookup_name='month')),
            day=(Extract(expression="created_at", lookup_name='day')),
            hour=(Extract(expression="created_at", lookup_name='hour')),
            minute=(Extract(expression="created_at", lookup_name='minute')),
            divided_minute=(Cast((F("minute") / 14), output_field=IntegerField())),
            time=Concat("year", "month", "day", "hour", "divided_minute")
        )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:57:06