Created
May 3, 2013 03:23
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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