Django: Post-QSRF Aggregation

I’m in the process of upgrading critify to the current SVN trunk, with QSRF now included. So far, everything is going smoothly, and I believe I am about done.

At one point in the project I need to let the database do a SUM()/COUNT() calculation. Not wanting to write the complete SQL manually, I had previously used a patched Django version that allowed me to retrieve the query generated by a QuerySet before it’s execution, replace the select clause, then send it through connection.execute().

Fortunately, with the new and improved QuerySet implementation, that’s a thing of the past now (and not only because you can now access the generated SQL via QuerySet.query.as_sql()!). While official aggregation support is still being worked on, the groundwork seems already in place:

qs = Review.objects.filter(**random_conditions)

# insert a custom select clause
class MyCustomSelect:
    def as_sql(self, quote_func):
        return "SUM(site_review.score)/COUNT(site_review.id)"
qs.query.select = [MyCustomSelect()]

# make sure it's the only thing we select
qs.query.related_select_cols = []
qs.query.select_related = False      # or related_select_cols is regenerated
qs.query.extra_select = {}

from django.db.models.sql.constants import SINGLE
return qs.query.execute_sql(SINGLE)[0]

As they say, Voila! 🙂

As a footnote, contrary to what I had heard upfront, I found the qsrf code remarkably easy to understand. Excellent job, Malcolm!

1 thought on “Django: Post-QSRF Aggregation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s