How to Get Two Random Records with Django

How to get two random records with Django

If you specify the random operator in the ORM I'm pretty sure it will give you two distinct random results won't it?

MyModel.objects.order_by('?')[:2] # 2 random results.

In Django, how do I select 100 random records from the database?

Content.objects.all().order_by('?')[:100]

See the order_by docs. Also be aware this approach does not scale well (in fact, it scales really, really badly). See this SO answer for a better way to handle random selection when you have large amounts of data.

How to pull a random record using Django's ORM?

Using order_by('?') will kill the db server on the second day in production. A better way is something like what is described in Getting a random row from a relational database.

from django.db.models.aggregates import Count
from random import randint

class PaintingManager(models.Manager):
def random(self):
count = self.aggregate(count=Count('id'))['count']
random_index = randint(0, count - 1)
return self.all()[random_index]

Get n number of random records using nested serializers Django REST framework

If you want N random questions of 1 exam, I would do the following:

  • Create a custom action in a Viewset (or a custom view)
    • It should be a DETAIL model action, meaning it looks like exams/3/your-action-name/
    • It should be a GET request
  • Then implement the following logic:
    • Fetch the exam model
    • Then fetch the Questions for that exam using "?" to order them randomly and only take a few
    • Then serialize the question instances
    • And return the data

Here's what it could look like:

def get_random_questions(self, request, pk=None):
exam = self.get_object()
questions = Question.objects.filter(exam=exam).order_by("?")[:5] # Update with your desired number
serializer = QuestionSerializer(questions, many=True)
return Reponse(serializer.data)

How do querysets work when getting multiple random objects from Django?

Simeon Popov's answer solves the problem, but let me explain where it comes from.

As you probably know querysets are lazy and won't be evaluated until it's necessary. They also have an internal cache that gets filled once the entire queryset is evaluated. If only a single object is taken from a queryset (or a slice with a step specified, i.e. [0:n:2]), Django evaluates it, but the results won't get cached.

Take these two examples:

Example 1

>>> people = Person.objects.order_by('?')[0:n]
>>> print(people[0].first_name, people[0].last_name)
# first and last name of different people

Example 2

>>> people = Person.objects.order_by('?')[0:n]
>>> for person in people:
>>> print(person.first_name, person.last_name)
# first and last name are properly matched

In example 1, the queryset is not yet evaluated when you access the first item. It won't get cached, so when you access the first item again it runs another query on the database.

In the second example, the entire queryset is evaluated when you loop over it. Thus, the cache is filled and there won't be any additional database queries that would change the order of the returned items. In that case the names are properly aligned to each other.

Methods for evaluating an entire queryset are a.o. iteration, list(), bool() and len(). There are some subtle differences between these methods. If all you want to do is make sure the queryset is cached, I'd suggest using bool(), i.e.:

>>> people = Person.objects.order_by('?')[0:n]
>>> bool(people)
True
>>> print(people[0].first_name, people[0].last_name)
# matching names

Django get a random object

Just been looking at this. The line:

random_object = A.objects.order_by('?')[0]

has reportedly brought down many servers.

Unfortunately Erwans code caused an error on accessing non-sequential ids.

There is another short way to do this:

import random

items = list(Product.objects.all())

# change 3 to how many random items you want
random_items = random.sample(items, 3)
# if you want only a single random item
random_item = random.choice(items)

The good thing about this is that it handles non-sequential ids without error.

Django: Get 10 random instances from a queryset and order them into a new queryset?

One thing you can do is take a list of ids (assuming, 'id' is the primary key) of random elements in the queryset, and then filter on those. Something like the code below:

import random
valid_profiles_id_list = ProfilePage.objects.filter(profileisbannedis=False).values_list('id', flat=True)
random_profiles_id_list = random.sample(valid_profiles_id_list, min(len(valid_profiles_id_list), 10))
query_set = ProfilePage.objects.filter(id__in=random_profiles_id_list)

Hope it helps, also please go through django queryset docs



Related Topics



Leave a reply



Submit