Skip to content

Instantly share code, notes, and snippets.

@mkhatib
Created May 3, 2013 03:23
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mkhatib/5506993 to your computer and use it in GitHub Desktop.
Save mkhatib/5506993 to your computer and use it in GitHub Desktop.
Abstract Random AppEngine ndb.Model. Extend this class and use .random method to get random entities/records.
import random
from google.appengine.ext import ndb
class RandomIndexedModel(ndb.Model):
"""Abstracts how we do randomness in the other models."""
random_index = ndb.FloatProperty('ri')
@classmethod
def random(cls, count=1, exclude=None, ancestor=None, filters=None):
exclude = exclude or []
filters = filters or []
# Get the count requested plus the excluded size and programatically
# remove the exclude list and return exactly the count requested.
extra_count = count+len(exclude)
query = cls.query(ancestor=ancestor) if ancestor else cls.query()
# If any filters is passed add it to the query.
for query_filter in filters:
query = query.filter(query_filter)
entities = query.filter(
cls.random_index >= random.random()).fetch(extra_count)
# If that fetch got less than count, get entities from the top of the list.
if not entities or len(entities) < extra_count:
entities = query.order(cls.random_index).fetch(extra_count)
# Remove exclude and return exact count.
entities = list(entity for entity in entities if not entity.key in exclude)
return entities[:count]
def _pre_put_hook(self):
self.random_index = random.random()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment