mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-25 11:04:02 +03:00
Optimizations play nicely with select_related, prefetch_related
This commit is contained in:
parent
720a37d3de
commit
ca7b1f6d51
|
@ -101,17 +101,7 @@ class RelatedField(Field):
|
|||
|
||||
def get_iterable(self, instance, source_attrs):
|
||||
relationship = get_attribute(instance, source_attrs)
|
||||
relationship = relationship.all() if (hasattr(relationship, 'all')) else relationship
|
||||
|
||||
if self.use_pk_only_optimization():
|
||||
# Optimized case, return mock objects only containing the pk attribute.
|
||||
return [
|
||||
PKOnlyObject(pk=pk)
|
||||
for pk in relationship.values_list('pk', flat=True)
|
||||
]
|
||||
|
||||
# Standard case, return the object instances.
|
||||
return relationship
|
||||
return relationship.all() if (hasattr(relationship, 'all')) else relationship
|
||||
|
||||
@property
|
||||
def choices(self):
|
||||
|
|
|
@ -92,6 +92,12 @@ class HyperlinkedManyToManyTests(TestCase):
|
|||
with self.assertNumQueries(4):
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
def test_many_to_many_retrieve_prefetch_related(self):
|
||||
queryset = ManyToManySource.objects.all().prefetch_related('targets')
|
||||
serializer = ManyToManySourceSerializer(queryset, many=True, context={'request': request})
|
||||
with self.assertNumQueries(2):
|
||||
serializer.data
|
||||
|
||||
def test_reverse_many_to_many_retrieve(self):
|
||||
queryset = ManyToManyTarget.objects.all()
|
||||
serializer = ManyToManyTargetSerializer(queryset, many=True, context={'request': request})
|
||||
|
|
|
@ -71,6 +71,12 @@ class PKManyToManyTests(TestCase):
|
|||
with self.assertNumQueries(4):
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
def test_many_to_many_retrieve_prefetch_related(self):
|
||||
queryset = ManyToManySource.objects.all().prefetch_related('targets')
|
||||
serializer = ManyToManySourceSerializer(queryset, many=True)
|
||||
with self.assertNumQueries(2):
|
||||
serializer.data
|
||||
|
||||
def test_reverse_many_to_many_retrieve(self):
|
||||
queryset = ManyToManyTarget.objects.all()
|
||||
serializer = ManyToManyTargetSerializer(queryset, many=True)
|
||||
|
@ -188,6 +194,12 @@ class PKForeignKeyTests(TestCase):
|
|||
with self.assertNumQueries(3):
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
def test_reverse_foreign_key_retrieve_prefetch_related(self):
|
||||
queryset = ForeignKeyTarget.objects.all().prefetch_related('sources')
|
||||
serializer = ForeignKeyTargetSerializer(queryset, many=True)
|
||||
with self.assertNumQueries(2):
|
||||
serializer.data
|
||||
|
||||
def test_foreign_key_update(self):
|
||||
data = {'id': 1, 'name': 'source-1', 'target': 2}
|
||||
instance = ForeignKeySource.objects.get(pk=1)
|
||||
|
|
|
@ -54,7 +54,14 @@ class SlugForeignKeyTests(TestCase):
|
|||
{'id': 2, 'name': 'source-2', 'target': 'target-1'},
|
||||
{'id': 3, 'name': 'source-3', 'target': 'target-1'}
|
||||
]
|
||||
self.assertEqual(serializer.data, expected)
|
||||
with self.assertNumQueries(4):
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
def test_foreign_key_retrieve_select_related(self):
|
||||
queryset = ForeignKeySource.objects.all().select_related('target')
|
||||
serializer = ForeignKeySourceSerializer(queryset, many=True)
|
||||
with self.assertNumQueries(1):
|
||||
serializer.data
|
||||
|
||||
def test_reverse_foreign_key_retrieve(self):
|
||||
queryset = ForeignKeyTarget.objects.all()
|
||||
|
@ -65,6 +72,12 @@ class SlugForeignKeyTests(TestCase):
|
|||
]
|
||||
self.assertEqual(serializer.data, expected)
|
||||
|
||||
def test_reverse_foreign_key_retrieve_prefetch_related(self):
|
||||
queryset = ForeignKeyTarget.objects.all().prefetch_related('sources')
|
||||
serializer = ForeignKeyTargetSerializer(queryset, many=True)
|
||||
with self.assertNumQueries(2):
|
||||
serializer.data
|
||||
|
||||
def test_foreign_key_update(self):
|
||||
data = {'id': 1, 'name': 'source-1', 'target': 'target-2'}
|
||||
instance = ForeignKeySource.objects.get(pk=1)
|
||||
|
|
Loading…
Reference in New Issue
Block a user