summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/core/serializers/python.py8
-rw-r--r--django/core/serializers/xml_serializer.py6
-rw-r--r--tests/serializers/tests.py13
3 files changed, 23 insertions, 4 deletions
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 5a5d8a7036..0ceb676e90 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -67,9 +67,11 @@ class Serializer(base.Serializer):
else:
def m2m_value(value):
return self._value_from_field(value, value._meta.pk)
- self._current[field.name] = [
- m2m_value(related) for related in getattr(obj, field.name).iterator()
- ]
+ m2m_iter = getattr(obj, '_prefetched_objects_cache', {}).get(
+ field.name,
+ getattr(obj, field.name).iterator(),
+ )
+ self._current[field.name] = [m2m_value(related) for related in m2m_iter]
def getvalue(self):
return self.objects
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 1f62c8e971..07de9428e7 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -132,7 +132,11 @@ class Serializer(base.Serializer):
self.xml.addQuickElement("object", attrs={
'pk': str(value.pk)
})
- for relobj in getattr(obj, field.name).iterator():
+ m2m_iter = getattr(obj, '_prefetched_objects_cache', {}).get(
+ field.name,
+ getattr(obj, field.name).iterator(),
+ )
+ for relobj in m2m_iter:
handle_m2m(relobj)
self.xml.endElement("field")
diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py
index 42044b5572..439464980d 100644
--- a/tests/serializers/tests.py
+++ b/tests/serializers/tests.py
@@ -250,6 +250,19 @@ class SerializersTestBase:
with self.assertNumQueries(0):
serializers.serialize(self.serializer_name, [mv])
+ def test_serialize_prefetch_related_m2m(self):
+ # One query for the Article table and one for each prefetched m2m
+ # field.
+ with self.assertNumQueries(3):
+ serializers.serialize(
+ self.serializer_name,
+ Article.objects.all().prefetch_related('categories', 'meta_data'),
+ )
+ # One query for the Article table, and two m2m queries for each
+ # article.
+ with self.assertNumQueries(5):
+ serializers.serialize(self.serializer_name, Article.objects.all())
+
def test_serialize_with_null_pk(self):
"""
Serialized data with no primary key results