Hi all,

I'm trying to write a utility method to retrieve generically related 
content (the particular model I'm using has the standard ContentType FK, 
object id and GenericFK) without ending up with one database hit per object:

http://dpaste.com/11633/
------------------------

from django.contrib.contenttypes.models import ContentType

def fetch_content_objects(item_queryset):
     """
     Populates the given items with their ContentTypes and content
     objects, grouping the retrieval of content objects by model type
     to reduce the number of queries executed.
     """
     items = list(item_queryset)

     # Group object ids by their content type ids
     objects_by_ctype = {}
     content_type_ids = set()
     for item in items:
         if not objects_by_ctype.has_key(item.content_type_id):
             objects_by_ctype[item.content_type_id] = []
         objects_by_ctype[item.content_type_id].append(item.object_id)
         content_type_ids.add(item.content_type_id)

     # Retrieve content types and content objects in bulk
     content_types = 
ContentType._default_manager.in_bulk(list(content_type_ids))
     for ctype_id, object_ids in objects_by_ctype.items():
         model = content_types[ctype_id].model_class()
         objects_by_ctype[ctype_id] = 
model._default_manager.in_bulk(object_ids)

     # Place content types and content objects in the appropriate items
     for item in items:
         item.content_type = content_types[item.content_type_id]
         item.object = 
objects_by_ctype[item.content_type_id][item.object_id]

     return items


So, I try to load and access the generic content for all the Items in my 
database at the moment (1744 of them at the moment). I can access the 
objects I've populated just fine without incurring any extra queries (12 
queries for 1744 objects. Woo! Yay!), but as soon as I try to access 
their content_type attributes...

http://dpaste.com/11634/
------------------------

 >>> from jellyroll.managers import fetch_content_objects
 >>> from jellyroll.models import Item
 >>> from django.db import connection
 >>> items = fetch_content_objects(Item.objects.all())
 >>> len(connection.queries)
12
 >>> len(items)
1744
 >>> [item.object for item in items]
...
 >>> len(connection.queries)
12
 >>> [item.content_type for item in items]
...
 >>> len(connection.queries)
1756

...I'm back to one-query-per-instanceville.

I've poked about a bit in 
django.db.models.fields.related.ReverseSingleRelatedObjectDescriptor, 
and even tried setting the '_content_type_cache' attribute it will 
eventually check for first in this particular case, but to no avail.

Has anyone done much work on "manually" populating related data? Any 
ideas how I can prevent that database hit per instance happening when I 
access the content_type attribute?

Thanks,
Jonathan

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to