【问题标题】:Filter QuerySet with a list of indexes使用索引列表过滤 QuerySet
【发布时间】:2015-01-02 21:13:33
【问题描述】:

我有一个这样的查询集

QS = SomeModel.objects.filter(some_filter='filter_value')

我需要从中随机选择 n 个元素,因此我生成了一个包含 0 到 QS 长度之间的 n 个随机数的列表,并将其放入列表变量 idx_list 中。

现在,我可以循环遍历 idx_list 并从 QS 一次提取一个元素,但是,我可以在一行中不循环吗?

【问题讨论】:

标签: python django django-queryset


【解决方案1】:

如果您想从 db 中获取项目,然后您可以使用 .order_by('?') 以随机顺序选择对象,然后生成 id 列表

您只能使用values_list() 以随机顺序获取 id

idx_list = SomeModel.objects.filter(some_filter='filter_value').order_by('?').values_list('id', flat=True)[:x]

或者你可以获取查询集:

QS = SomeModel.objects.filter(some_filter='filter_value').order_by('?')

然后切片任意数量的项目:

# Get id's of random x elements
idx_list = map(lambda item: item.id, list(QS[0:x]))

【讨论】:

  • 请注意,这种方法会让你的服务器爬到一个角落里哭几个星期,在它成为磁盘 I/O 的瓶颈之前填满内存,并且在它吐出结果之前不响应任何人或任何东西这可以在不到一秒钟的时间内实现。请忘记曾经存在过的order_by('?')
  • 不是每个人都有超过 10 万条记录的数据库表。不是每个人都需要在简单的情况下使用花哨的解决方案。
  • 感谢 Secator,但我担心 '?' 的性能,因为我需要对每个用户请求的数千个条目重复此过滤几次,并且随时可能有几千个用户。我现在保持循环:[QS(j) for j in random.sample(range(1, len(QS)), n)],你怎么看?
猜你喜欢
  • 2018-10-29
  • 2012-12-19
  • 2015-08-30
  • 2012-08-04
  • 2013-09-19
  • 2020-01-01
  • 2018-06-24
  • 2018-01-21
相关资源
最近更新 更多