myqueryset = Content.objects.filter(random 100)
3 Answers
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.
-
7And the all() is redundant, but I never remember that. – Tom Aug 17 '10 at 20:33
-
1This is awesome! Through debugging, I have noticed it even generates a good query, only grabbing 20 elements, using 1 query, using ORDER BY RAND() for random. Good god, that's fantastic. – John Chadwick Nov 24 '13 at 19:37
-
1Really good tool for development when model data is being imported from another source and you're looking for quirks. – pspahn Feb 14 '22 at 22:36
If you're going to do this more than once, you need to design this into your database.
If you're doing it once, you can afford to pay the hefty penalty. This gets you exactly 100 with really good random properties. However, it uses a lot of memory.
pool= list( Content.objects.all() )
random.shuffle( pool )
object_list = pool[:100]
Here's another algorithm that's also kind of slow since it may search the entire table. It doesn't use very much memory at all and it may not get exactly 100.
total_count= Content.objects.count()
fraction = 100./total_count
object_list = [ c for c in Content.objects.all() if random.random() < fraction ]
If you want to do this more than once, you need to add an attribute to Content to allow effective filtering for "random" values. For example, you might do this.
class Content( models.Model ):
... etc. ...
def subset( self ):
return self.id % 32768
This will partition your data into 32768 distinct subsets. Each subset is 1/32768'th of your data. To get 100 random items, you need 100*32768/total_count subsets of your data.
total_count = Content.objects.count()
no_of_subsets= 100*32768/total_count
object_list = Content.objects.filter( subset__lte=no_of_subsets )
This is fast and it's reproducible. The subsets are "arbitrary" not technically "random".

- 384,516
- 81
- 508
- 779
-
I like your last approach although I don't think you can filter on properties. You'd have to add the subset column in the model itself and set it's value on save like this: http://ifacethoughts.net/2009/07/14/calculated-fields-in-django/ – jesal Aug 31 '12 at 18:06
-
Adding subset as a method to the Content model is not enough to filter on it, as suggested in your last snippet. – Peter Kilczuk May 31 '13 at 16:55
I do:
import random
object_list = list(Content.objects.filter(foo=bar).values()[:100])
random.shuffle(object_list)
Runs only single-simple MySQL query and is good on performance.

- 5,108
- 6
- 41
- 63
-
2This does not return random records from the database. It picks the first hundred record and shuffles them. Records 101 onwards have no chance of getting selected. – Blair Jun 05 '12 at 12:58
-
I meant to suggest the usage of shuffle function over order_by('?') which has serious performance issues: http://stackoverflow.com/a/6405601/232649 For shuffling all records: shuffle(list(Content.objects.all()))[:100] – Pratyush Jun 05 '12 at 13:10