首页 > 解决方案 > 注释日期时间字段的特定属性 - 无法将关键字“toordinal”解析为字段。不允许加入“created_at”

问题描述

我正在为网站上的帖子开发评分系统。它认为其他关系字段(评论、视图和反应表情符号)有更深入的方式来排序结果。

但由于不希望有热门帖子,而且太旧,在首页,我决定考虑帖子创建时间。

问题是,DateTime 值太精确,按它排序会完全忽略评分系统并返回简单的按时间顺序排列的提要。

在测试一些解决方案时,我尝试使用 toordinal 构建函数来使用一个值来表示自第 1 年 1 月 1 日以来经过的天数。我的想法是将这个值与 post_hour 和 (post_minute // 14) 的结果连接起来。这样,将有一个 14 分钟的窗口,在此窗口中,所有帖子将完全按其分数排序。它看起来足够好,任何调整都很简单。

查看一些 SO 帖子和 Django 文档,我发现我可以通过在 F 表达式中使用 dunder 传递我试图访问的属性来做到这一点:

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.

那是我第一次使用注释,所以我现在有点迷路了。

编辑:明白了!在进行更多测试并确保这不会减慢查询速度后,我将把它作为答案发布。

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")
        )

标签: pythondjangodjango-ormpython-datetimedjango-annotate

解决方案


推荐阅读