title: Django random object manager
link: http://jj.isgeek.net/2011/03/django-random-object-manager/
author: Jj
description: 
post_id: 633
date: 2011/03/02 23:15:11
created_gmt: 2011/03/03 04:15:11
comment_status: open
slug: django-random-object-manager

Several times in the past I needed to fetch a list of random objects. And Today I decided to make a Mixin class to add a get_random() method to my managers: 
    
    
    
    
    
    
    
    
    
    
    
    # -*- coding: utf-8 -*-
    
    
    
    
    
    
    
    
    
    from random import sample
    
    
    
    
    
    
    
    
    
    class RandomObjectManager(object):
    
    
    
    
        """
    
    
    
    
        Manager Mixin to implement get_random() in your models.
    
    
    
    
        You can override get_objects to tune the queriset
    
    
    
    
    
    
    
    
    
        To use, define your class:
    
    
    
    
    
    
    
    
    
        class MyManager(models.Manager, RandomObjectManager):
    
    
    
    
            DEFAULT_NUMBER = 5 # I can change that
    
    
    
    
    
    
    
    
    
            def get_objects(self):
    
    
    
    
                return self.filter(active=True) # Only active models plz
    
    
    
    
    
    
    
    
    
        class MyModel(models.Model):
    
    
    
    
            active = models.BooleanField()
    
    
    
    
            objects = MyManager()
    
    
    
    
    
    
    
    
    
        Now you can do:
    
    
    
    
        MyModel.objects.get_random()
    
    
    
    
    
    
    
    
    
        """
    
    
    
    
    
    
    
    
    
        DEFAULT_NUMBER = 3
    
    
    
    
    
    
    
    
    
        def get_objects(self):
    
    
    
    
            return self.all()
    
    
    
    
    
    
    
    
    
        def get_random(self, number=DEFAULT_NUMBER):
    
    
    
    
            """
    
    
    
    
            Returns a set of random objects
    
    
    
    
            """
    
    
    
    
            ids = self.get_objects().values_list('id', flat=True)
    
    
    
    
            amount = min(len(ids), number)
    
    
    
    
            picked_ids = sample(ids, amount)
    
    
    
    
            return self.filter(id__in=picked_ids)
    
    
    
    
    
    
    
    
    
    

I've added this as a [Django snippet](http://djangosnippets.org/snippets/2380/) and as a [Gist](https://gist.github.com/852323).

## Comments

**[fish2000](#370625 "2011-06-16 21:52:00"):** Hey, nice implementation w/ the inner class sir. Just an FYI tho: in my own investigations with this sort of thing, I found that calling random.seed() in the manager's __init__() method was necessary, to ensure the most randomish results.

**[Thomas Woolford](#371207 "2012-06-25 23:19:00"):** Surely this is less of a performance killer than reading *every* ID from the entire table and then making another separate query to grab the objects that you actually need....

**[Thomas Woolford](#371204 "2012-06-21 01:46:00"):** ]

**[Jj](#371205 "2012-06-21 14:25:00"):** https://code.djangoproject.com/ticket/5267

**[Fernando Gutierrez](#369330 "2011-03-03 14:47:18"):** Aren't you supposed to use get_objects() instead?

**[Jj](#369334 "2011-03-03 19:58:00"):** Yes! I just fixed that, thanks

