Select 3 random items and exclude the one already selected

Question:

I’m trying to display three random drinks in my template, selected from a database of drinks.
I currently have the random selection working but also noticed theres a chance of a drink showing up twice.
How do I prevent this from happening? Is there a smarter way of doing this?

import random
def testview(request):

   
    drink1 = random.choice(DrinkRecipe.objects.all())
    drink2 = random.choice(DrinkRecipe.objects.all())
    drink3 = random.choice(DrinkRecipe.objects.all())


    context ={
            'drink1' : drink1,
            'drink2' : drink2,
            'drink3' : drink3,
        }

    return render(request,'drinks/test.html', context=context)
Asked By: Thomas Doll-Datema

||

Answers:

I would use:

drinks = DrinkRecipe.objects.all().order_by("?")[:3]
context = {"drinks": drinks}
Answered By: zotil

You can prevent duplicate drinks from being selected by using the sample() function from the random module.
You can try this approach, considering you are using Django

import random
from django.core.exceptions import ObjectDoesNotExist

def testview(request):
    try:
        drinks = random.sample(list(DrinkRecipe.objects.all()), 3)
    except ValueError:
        # Handle the case when there are fewer than 3 drinks in the database
        drinks = list(DrinkRecipe.objects.all())

    context = {
        'drink1': drinks[0] if len(drinks) > 0 else None,
        'drink2': drinks[1] if len(drinks) > 1 else None,
        'drink3': drinks[2] if len(drinks) > 2 else None,
    }

    return render(request, 'drinks/test.html', context=context)

This code attempts to pick 3 different drinks randomly using the random.sample() function. If there are less than 3 drinks in the database, it catches an error and just uses all the available drinks. Finally, it adds the drinks to the context, making sure that no repeated drinks are shown in the template.

Answered By: Hasan Patel