我尝试以这种方式从已经过滤的查询集中提取一个随机对象:
Product.objects.filter(active=True).order_by('?').first()
目前它是用.order_by('?')
解决的,但似乎很慢。
我试图按照我的观点来解决这个问题。
它不起作用,所以我不确定我做这件事的方式是否正确。
products = Product.objects.filter(
active=True,
)
count = products.aggregate(count=Count('id'))['count']
random_index = randint(0, count - 1)
product = products[random_index]
这是我现在的代码,它抛出ValueError:
ValueError: low >= high
请帮我加快速度。
如果.order_by('?')
太慢,一个不错的选择(取决于产品数量(可能是查询项目的PKs,然后随机选择一个:
qs = Product.objects.filter(active=True)
pks = list(qs.values_list('id', flat=True))
random_pk = random.choice(active_product_pks)
random_item = qs.get(pk=random_pk)
如果符合您的业务需求,您也可以在Django缓存中缓存pks
一段时间。
您可以这样做:
import random
products = Product.objects.filter(
active=True,
)
items = list(products)
# if you want only a single random item
random_item = random.choice(items)
或者这个:
from random import randint
count = Product.objects.count()
try:
random_choice = randint(0, count - 1)
except:
# if count == 0 then it will raise a ValueError.
random_choice = 0
random_object = Product.objects.none()
if random_choice > 0:
random_object = Product.objects.all()[random_choice]
p.s1:第二种解决方案更有效
P.s2:不要使用order_by('?')
。