def get_top self Model limit 10 reversed False Get the top scored obje

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
def get_top(self, Model, limit=10, reversed=False):
"""
Get the top N scored objects for a given model.
Yields (object, score) tuples.
"""
ctype = ContentType.objects.get_for_model(Model)
query = """
SELECT object_id, SUM(vote) as %s
FROM %s
WHERE content_type_id = %%s
GROUP BY object_id""" % (
qn('score'),
qn(self.model._meta.db_table),
)
# MySQL has issues with re-using the aggregate function in the
# HAVING clause, so we alias the score and use this alias for
# its benefit.
if settings.DATABASE_ENGINE == 'mysql':
having_score = qn('score')
else:
having_score = 'SUM(vote)'
if reversed:
having_sql = ' HAVING %(having_score)s < 0 ORDER BY %(having_score)s ASC %(limit_offset)s'
else:
having_sql = ' HAVING %(having_score)s > 0 ORDER BY %(having_score)s DESC %(limit_offset)s'
query += having_sql % {
'having_score': having_score,
'limit_offset': "LIMIT %s" % limit, #connection.ops.limit_offset_sql(limit),
}
cursor = connection.cursor()
cursor.execute(query, [ctype.id])
results = cursor.fetchall()
# Use in_bulk() to avoid O(limit) db hits.
objects = Model.objects.in_bulk([id for id, score in results])
# Yield each object, score pair. Because of the lazy nature of generic
# relations, missing objects are silently ignored.
for id, score in results:
if id in objects:
yield objects[id], int(score)