Added exec_js and sum functions to QuerySet

This commit is contained in:
Harry Marr 2009-12-30 15:14:18 +00:00
parent 90e5e5dfa9
commit 2cc68b46ad
2 changed files with 36 additions and 4 deletions

View File

@ -195,12 +195,37 @@ class QuerySet(object):
def __iter__(self): def __iter__(self):
return self return self
def exec_js(self, code, fields):
"""Execute a Javascript function on the server. Two arguments will be
provided by default - the collection name, and the query object. A list
of fields may be provided, which will be translated to their correct
names and supplied as the remaining arguments to the function.
"""
fields = [QuerySet._translate_field_name(self._document, field)
for field in fields]
db = _get_db()
collection = self._document._meta['collection']
return db.eval(code, collection, self._query, *fields)
def sum(self, field):
"""Sum over the values of the specified field.
"""
sum_func = """
function(collection, query, sumField) {
var total = 0.0;
db[collection].find(query).forEach(function(doc) {
total += doc[sumField] || 0.0;
});
return total;
}
"""
return self.exec_js(sum_func, [field])
def item_frequencies(self, list_field): def item_frequencies(self, list_field):
"""Returns a dictionary of all items present in a list field across """Returns a dictionary of all items present in a list field across
the whole queried set of documents, and their corresponding frequency. the whole queried set of documents, and their corresponding frequency.
This is useful for generating tag clouds, or searching documents. This is useful for generating tag clouds, or searching documents.
""" """
list_field = QuerySet._translate_field_name(self._document, list_field)
freq_func = """ freq_func = """
function(collection, query, listField) { function(collection, query, listField) {
var frequencies = {}; var frequencies = {};
@ -212,9 +237,7 @@ class QuerySet(object):
return frequencies; return frequencies;
} }
""" """
db = _get_db() return self.exec_js(freq_func, [list_field])
collection = self._document._meta['collection']
return db.eval(freq_func, collection, self._query, list_field)
class QuerySetManager(object): class QuerySetManager(object):

View File

@ -214,6 +214,15 @@ class QuerySetTest(unittest.TestCase):
BlogPost.drop_collection() BlogPost.drop_collection()
def test_sum(self):
"""Ensure that field can be summed over correctly.
"""
ages = [23, 54, 12, 94, 27]
for i, age in enumerate(ages):
self.Person(name='test%s' % i, age=age).save()
self.assertEqual(int(self.Person.objects.sum('age')), sum(ages))
def test_custom_manager(self): def test_custom_manager(self):
"""Ensure that custom QuerySetManager instances work as expected. """Ensure that custom QuerySetManager instances work as expected.
""" """