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
相关产品推荐
相关产品推荐

