Login

Manager method for limiting GenericForeignKey queries

Author:
zerok
Posted:
August 15, 2008
Language:
Python
Version:
.96
Score:
7 (after 7 ratings)

This is a simple manager that offers one additional method called relate, which fetches generic foreign keys (as referenced by content_type and object_id fields) without requiring one additional query for each contained element.

Basically, when working with generic foreign keys (and esp. in the usecase of having something like a tumblelog where you use an additional model just to have a single sorting point of multiple other models), don't do something like result = StreamItem.objects.select_related() but just fetch the content type with result = StreamItem.objects.select_related('content_type'), otherwise you will end up with first one query for the list of StreamItems but then also with one additional query for each item contained in this resultset.

When you now combine the latter call with result = StreamItem.gfkmanager.relate(result), you will just get the one query for the item list + one query for each content type contained in this list (if the models have already been cached).

For further details, please read this post on my blog.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
from django.db import models

class GFKManager(models.Manager):
    def relate(self, qs):
        model_map = {}
        item_map = {}
        for item in qs:
            model_map.setdefault(item.content_type, {}) \
                [item.object_id] = item.id
            item_map[item.id] = item
        for ct, items_ in model_map.items():
            for o in ct.model_class().objects.select_related() \
                    .filter(id__in=items_.keys()).all():
                item_map[items_[o.id]].content_object = o
        return qs

More like this

  1. "Magic Link" Management Command by webology 3 months ago
  2. Closest ORM models to a latitude/longitude point by simonw 3 months ago
  3. Log the time taken to execute each DB query by kennyx46 3 months ago
  4. django database snippet by ItsRLuo 3 months, 1 week ago
  5. Serialize a model instance by chriswedgwood 4 months ago

Comments

Please login first before commenting.