django - 通过使用 redis 列表进行过滤来控制 Django 查询集结果的排序

标签 django redis django-views django-queryset

在我的 Django 网站上,用户贡献帖子,然后在主页上全局显示,按最新排序。

我通过将所有 post_id 执行 lpush 到一个 redis 列表中(该列表保持 1000 个条目),将 redis 引入到这个组合中。代码是:

def add_post(link_id):
    my_server = redis.Redis(connection_pool=POOL)
    my_server.lpush("posts:1000", link_id)
    my_server.ltrim("posts:1000", 0, 9999)

然后,当用户请求主页的内容时,我只需在相关的基于类的 View 的get_queryset 方法中执行以下查询:

Post.objects.filter(id__in=all_posts())

其中 all_posts() 很简单:

def all_posts():
    my_server = redis.Redis(connection_pool=POOL)
    return my_server.lrange("posts:1000", 0, -1)

接下来,我遍历 Django 模板中的 context["object_list"](即 {% for post in object_list %},并一个接一个地填充供我的用户查看的最新帖子。

我的问题是这种安排不会首先显示最新的。它总是最后显示最新的。所以我把lpush改成了rpush但是结果一点都没变。为什么改redis的list insert方法没有变Django 的查询集返回给我的结果的顺序?

也许我遗漏了一些基本的东西。请告诉我发生了什么,我该如何解决这个问题({% for post in object_list reversed %} 我唯一的选择)。我选择 redis 路线的原因自然是性能。在使用 Redis 之前,我会这样做:Post.objects.order_by('-id')[:1000] 在此先感谢。

注意:如有需要,请询问更多信息

最佳答案

您正在遍历一个没有 order_by 子句的查询集,这意味着您不能对顺序或结果有任何期望。 __in 子句只控制返回哪些行,而不是它们的顺序。

返回结果按id 顺序的事实是一个实现细节。如果你想依赖它,你可以以相反的顺序遍历查询集。一个更强大的解决方案是根据从 Redis 返回的 ID 的顺序重新排序(在 Python 中)实例。

尽管如此,我认为在这里使用 Redis 不会有任何性能优势。我认为任何具有 id 索引的关系数据库都能够非常有效地执行 Post.objects.order_by('-id')[:1000]。 (请注意,对查询集进行切片会对数据库执行 LIMIT;您不会将所有行提取到 Python 中,然后对一个巨大的列表进行切片。)

关于django - 通过使用 redis 列表进行过滤来控制 Django 查询集结果的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38576929/

相关文章:

python - Django 报错邮件——自定义设置参数

python - 如何在 django rest 框架中保存嵌套关系?

python-3.x - parse() 缺少 1 个必需的位置参数 : 'stream'

django - 如何在 python django 中使用一些匹配的字母而不是完全匹配来过滤查询结果?

html - 如何使用 bootstrap 格式化文本以换行到第二行?

redis - 如何知道redis的master/slave状态?

redis - 重置 Redis "used_memory_peak"统计

javascript - Express 没有找到它期望的 redis 结果

Django根据外键对字段求和

Django: "primary_key=True"也指 "unique"吗?