Fixed #17991 - prefetch_related fails with GenericRelation and varchar ID field
Thanks to okke@formsma.nl for the report, and carmandrew@gmail.com for the tests.
This commit is contained in:
parent
4ea8105120
commit
4c4d08502c
|
@ -5,7 +5,6 @@ from __future__ import unicode_literals
|
|||
|
||||
from collections import defaultdict
|
||||
from functools import partial
|
||||
from operator import attrgetter
|
||||
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import connection
|
||||
|
@ -329,8 +328,11 @@ def create_generic_related_manager(superclass):
|
|||
set(obj._get_pk_val() for obj in instances)
|
||||
}
|
||||
qs = super(GenericRelatedObjectManager, self).get_query_set().using(db).filter(**query)
|
||||
# We (possibly) need to convert object IDs to the type of the
|
||||
# instances' PK in order to match up instances:
|
||||
object_id_converter = instances[0]._meta.pk.to_python
|
||||
return (qs,
|
||||
attrgetter(self.object_id_field_name),
|
||||
lambda relobj: object_id_converter(getattr(relobj, self.object_id_field_name)),
|
||||
lambda obj: obj._get_pk_val(),
|
||||
False,
|
||||
self.prefetch_cache_name)
|
||||
|
|
|
@ -125,6 +125,10 @@ class TaggedItem(models.Model):
|
|||
related_name='taggeditem_set3')
|
||||
created_by_fkey = models.PositiveIntegerField(null=True)
|
||||
created_by = generic.GenericForeignKey('created_by_ct', 'created_by_fkey',)
|
||||
favorite_ct = models.ForeignKey(ContentType, null=True,
|
||||
related_name='taggeditem_set4')
|
||||
favorite_fkey = models.CharField(max_length=64, null=True)
|
||||
favorite = generic.GenericForeignKey('favorite_ct', 'favorite_fkey')
|
||||
|
||||
def __str__(self):
|
||||
return self.tag
|
||||
|
@ -132,7 +136,11 @@ class TaggedItem(models.Model):
|
|||
|
||||
class Bookmark(models.Model):
|
||||
url = models.URLField()
|
||||
tags = generic.GenericRelation(TaggedItem)
|
||||
tags = generic.GenericRelation(TaggedItem, related_name='bookmarks')
|
||||
favorite_tags = generic.GenericRelation(TaggedItem,
|
||||
content_type_field='favorite_ct',
|
||||
object_id_field='favorite_fkey',
|
||||
related_name='favorite_bookmarks')
|
||||
|
||||
|
||||
class Comment(models.Model):
|
||||
|
|
|
@ -319,6 +319,16 @@ class GenericRelationTests(TestCase):
|
|||
for t in b.tags.all()]
|
||||
self.assertEqual(sorted(tags), ["django", "python"])
|
||||
|
||||
def test_charfield_GFK(self):
|
||||
b = Bookmark.objects.create(url='http://www.djangoproject.com/')
|
||||
t1 = TaggedItem.objects.create(content_object=b, tag='django')
|
||||
t2 = TaggedItem.objects.create(content_object=b, favorite=b, tag='python')
|
||||
|
||||
with self.assertNumQueries(3):
|
||||
bookmark = Bookmark.objects.filter(pk=b.pk).prefetch_related('tags', 'favorite_tags')[0]
|
||||
self.assertEqual(sorted([i.tag for i in bookmark.tags.all()]), ["django", "python"])
|
||||
self.assertEqual([i.tag for i in bookmark.favorite_tags.all()], ["python"])
|
||||
|
||||
|
||||
class MultiTableInheritanceTest(TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue