summaryrefslogtreecommitdiff
path: root/django/core
diff options
context:
space:
mode:
authorVIZZARD-X <vigneshanandmay13@gmail.com>2025-12-27 13:54:14 +0530
committerJacob Walls <jacobtylerwalls@gmail.com>2026-02-26 07:46:35 -0500
commite6108b7388775f4996a5906e0525fbdd40d2df51 (patch)
treecc84128dc376980dac983f369193d3f3309f530f /django/core
parentf991a1883889a520679fe41112281435581211e1 (diff)
Fixed #36750 -- Made ordering of M2M objects deterministic in serializers.
Co-authored-by: Simon Charette <charette.s@gmail.com> Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
Diffstat (limited to 'django/core')
-rw-r--r--django/core/serializers/python.py17
-rw-r--r--django/core/serializers/xml_serializer.py17
2 files changed, 32 insertions, 2 deletions
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 53a73e19e5..73ba24368b 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -77,7 +77,15 @@ class Serializer(base.Serializer):
chunk_size = (
2000 if getattr(attr, "prefetch_cache_name", None) else None
)
- return attr.iterator(chunk_size)
+ query_set = attr.all()
+ if not query_set.totally_ordered:
+ current_ordering = (
+ query_set.query.order_by
+ or query_set.model._meta.ordering
+ or []
+ )
+ query_set = query_set.order_by(*current_ordering, "pk")
+ return query_set.iterator(chunk_size)
else:
@@ -86,6 +94,13 @@ class Serializer(base.Serializer):
def queryset_iterator(obj, field):
query_set = getattr(obj, field.name).select_related(None).only("pk")
+ if not query_set.totally_ordered:
+ current_ordering = (
+ query_set.query.order_by
+ or query_set.model._meta.ordering
+ or []
+ )
+ query_set = query_set.order_by(*current_ordering, "pk")
chunk_size = 2000 if query_set._prefetch_related_lookups else None
return query_set.iterator(chunk_size=chunk_size)
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index d8ffbdf00a..3d1f79ea0d 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -177,7 +177,15 @@ class Serializer(base.Serializer):
chunk_size = (
2000 if getattr(attr, "prefetch_cache_name", None) else None
)
- return attr.iterator(chunk_size)
+ query_set = attr.all()
+ if not query_set.totally_ordered:
+ current_ordering = (
+ query_set.query.order_by
+ or query_set.model._meta.ordering
+ or []
+ )
+ query_set = query_set.order_by(*current_ordering, "pk")
+ return query_set.iterator(chunk_size)
else:
@@ -186,6 +194,13 @@ class Serializer(base.Serializer):
def queryset_iterator(obj, field):
query_set = getattr(obj, field.name).select_related(None).only("pk")
+ if not query_set.totally_ordered:
+ current_ordering = (
+ query_set.query.order_by
+ or query_set.model._meta.ordering
+ or []
+ )
+ query_set = query_set.order_by(*current_ordering, "pk")
chunk_size = 2000 if query_set._prefetch_related_lookups else None
return query_set.iterator(chunk_size=chunk_size)