[Django]-How to get a random element of the filtered queryset efficiently?

2πŸ‘

βœ…

If .order_by('?') is too slow, a decent option (depending on the number of products) might be to query for the PKs of the items, then pick one at random:

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)

You could cache pks in the Django cache for a while, too, if that suits your business requirements.

πŸ‘€AKX

2πŸ‘

you can do this:

import random

products = Product.objects.filter(
    active=True,
)
items = list(products)

# if you want only a single random item
random_item = random.choice(items)  

or this one:

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: Second solution is more efficient.
P.s2: Don’t use order_by('?').

Leave a comment