﻿id summary reporter owner description type status component version severity resolution keywords cc stage has_patch needs_docs needs_tests needs_better_patch easy ui_ux 17838 prefetch_related fails for GenericForeignKeys when related object id is not a CharField/TextField mkai anonymous "After a ton of debugging, I finally found the reason why my prefetching wasn't working. Here's a simple test case with the comments framework: {{{ from django.contrib.comments.models import Comment for c in Comment.objects.all().prefetch_related('content_object'): ... print c.content_object ... SELECT * FROM ""django_comments"" ORDER BY ""django_comments"".""submit_date"" ASC [3.67ms] SELECT * FROM ""django_content_type"" WHERE ""django_content_type"".""id"" = 15 [1.42ms] SELECT * FROM ""items_item"" WHERE ""items_item"".""id"" IN (709, 79) ORDER BY ""items_item"".""created"" DESC [2.48ms] SELECT * FROM ""items_item"" WHERE ""items_item"".""id"" = 79 [0.79ms] SELECT * FROM ""items_item"" WHERE ""items_item"".""id"" = 709 [1.00ms] }}} As you can see, it's doing the IN query, but then issues another query for each item. The ```object_pk``` field on ```Comment``` is a TextField, but the id field on ```Item``` is an IntegerField. This has the effect that the cache lookup no longer works. It looks up a tuple like ```(79, )```, but the cache has a tuple like ```(u'79', )``` set. A quick fix is to simply convert the value to an int in contrib.contenttypes.generic.py: {{{ def gfk_key(obj): ct_id = getattr(obj, ct_attname) if ct_id is None: return None else: # QUICK FIX: convert to int to fix cache lookups # return (getattr(obj, self.fk_field), return (int(getattr(obj, self.fk_field)), self.get_content_type(id=ct_id, using=obj._state.db).model_class()) }}} That is probably a very naive solution. Maybe one should check the type of the related object's field and then (safely) convert the value based on that? " Bug closed contrib.contenttypes master Release blocker fixed prefetch_related Accepted 1 0 0 0 0 0