Snippet List
This is an improvement on [snippet 1079](http://www.djangosnippets.org/snippets/1079/). Please read its description and [this blog post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) for any information.
This is a manager for handling generic foreign key. Generic foreign objects of the same type are fetched together in order to reduce the number of SQL queries.
To use, just assign an instance of GFKManager as the objects attribute of a model that has generic foreign keys. Then:
`MyModelWithGFKs.objects.filter(...).fetch_generic_relations()`
The generic related items will be bulk-fetched to minimize the number of queries.
**Improvement:** Problem I had with previous version from snippet 1079 : if two or more items shares the same generic foreign object, then only the first one is cached. Next ones generates new unwanted SQL queries. I solved this problem by putting all the needed foreign objects in a temporary data_map dictionary. Then, the objects are distributed to every items, so that if two items shares the same foreign object, it will only be fetched once.
- foreignkey
- generic
- manager
- query
- tuning
This is an improvement on [snippet 984](http://www.djangosnippets.org/snippets/984/). Read it's description and [this blog post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) for good explanations of the problem this solves.
Unlike snippet 984, this version is able to handle multiple generic foreign keys, generic foreign keys with nonstandard ct_field and fk_field names, and avoids unnecessary lookups to the ContentType table.
To use, just assign an instance of GFKManager as the objects attribute of a model that has generic foreign keys. Then:
MyModelWithGFKs.objects.filter(...).fetch_generic_relations()
The generic related items will be bulk-fetched to minimize the number of queries.
- foreignkey
- generic
- manager
- query
- tuning
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](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) on my blog.
- foreignkey
- generic
- manager
- query
- tuning
3 snippets posted so far.