如何使用Django获取两个不同的随机记录?我已经看到了关于如何获得一个的问题,但我需要获得两个随机记录,它们必须不同。
答案 0 :(得分:96)
对于具有大量行的表,其他答案建议的order_by('?')[:2]
解决方案实际上是一件非常糟糕的事情。它会导致ORDER BY RAND()
SQL查询。作为一个例子,这里是mysql如何处理(其他数据库的情况没有太大差别)。想象一下你的桌子有十亿行:
ORDER BY RAND()
,需要RAND()
列进行排序。注意:只是为了一点额外的肉汁,请注意mysql最初会尝试在RAM中创建临时表。当它耗尽时,它会将所有内容都保留下来,将整个内容复制到磁盘上,这样就可以在几乎整个过程中获得额外的I / O瓶颈。
怀疑者应该查看生成的查询,以确认它是ORDER BY RAND()
然后是谷歌“按rand()排序”(带引号)。
更好的解决方案是将一个真正昂贵的查询交换为三个便宜的查询(限制/偏移而不是ORDER BY RAND()
):
import random
last = MyModel.objects.count() - 1
index1 = random.randint(0, last)
# Here's one simple way to keep even distribution for
# index2 while still gauranteeing not to match index1.
index2 = random.randint(0, last - 1)
if index2 == index1: index2 = last
# This syntax will generate "OFFSET=indexN LIMIT=1" queries
# so each returns a single record with no extraneous data.
MyObj1 = MyModel.objects.all()[index1]
MyObj2 = MyModel.objects.all()[index2]
答案 1 :(得分:23)
如果在ORM中指定随机运算符我很确定它会给你两个截然不同的随机结果吗?
MyModel.objects.order_by('?')[:2] # 2 random results.
答案 2 :(得分:8)
为未来的读者。
获取所有记录的ID列表:
my_ids = MyModel.objects.values_list('id', flat=True)
my_ids = list(my_ids)
然后从以上所有ID中选择n个随机ID:
n = 2
rand_ids = random.sample(my_ids, n)
获取这些ID的记录:
random_records = MyModel.objects.filter(id__in=rand_ids)
答案 3 :(得分:6)
Object.objects.order_by('?')[:2]
这将返回两个随机排序的记录。你可以添加
distinct()
如果数据集中有相同值的记录。
答案 4 :(得分:3)
关于从序列中采样n个随机值,可以使用随机库,
random.Random().sample(range(0,last),2)
将从序列元素中取出2个随机样本,0到last-1
答案 5 :(得分:0)
from django.db import models
from random import randint
from django.db.models.aggregates import Count
class ProductManager(models.Manager):
def random(self, count=5):
index = randint(0, self.aggregate(count=Count('id'))['count'] - count)
return self.all()[index:index + count]
您可以获得不同数量的对象。