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
- improved generic foreign key manager by carljm 4 years, 9 months ago
- Improved generic foreign key manager 2 by Nomalz 3 years, 7 months ago
- EditInline for GenericForeignKey by king 5 years, 1 month ago
- Admin Hack: Quick lookup of GenericForeignKey id by ContentType by adnan 4 years, 8 months ago
- URL models by diverman 3 years, 8 months ago
Comments
This is really nice. A few issues I've observed with it:
1) Referring to item.content_type causes n queries to the ContentType table which bypass its lookup cache. This could easily be addressed by storing the content type id instead and using ContentType.objects.get_for_id, which goes through the cache.
2) This snippet makes assumptions about the names of the content_type and object_id fields used for the GenericForeignKey. It would be more robust to pull this information from the GFK itself.
3) This would be easier to use if it were a method on a queryset of the model with a GFK, so you could just say "StreamItem.objects.filter(...).fetch_generic_relations()" and have it done in one command.
I've posted a version that addresses these issues here.
#
New improved version here.
#