Skip to content

Commit 88a26df

Browse files
author
Maxime Toussaint
committed
Merge branch 'main' of github.com:MaxDude132/drf-serializer-prefetch
2 parents 6a8b545 + b743720 commit 88a26df

File tree

2 files changed

+59
-11
lines changed

2 files changed

+59
-11
lines changed

serializer_prefetch/base.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
from collections.abc import Iterable
33

44
# Django
5-
from django.db.models import Model, Prefetch, QuerySet, prefetch_related_objects
5+
from django.db.models import (
6+
Manager,
7+
Model,
8+
Prefetch,
9+
QuerySet,
10+
prefetch_related_objects,
11+
)
612
from django.utils.translation import gettext as _
713

814
# Rest Framework
9-
from rest_framework import serializers
15+
from rest_framework import serializers, relations
1016
from rest_framework.fields import empty
1117

1218
from serializer_prefetch.utils import (
@@ -212,14 +218,19 @@ def _get_all_prefetch_with_to_attr(self, serializer):
212218
)
213219

214220
def _get_fields(self, serializer: serializers.Serializer):
221+
if not hasattr(serializer, "fields"):
222+
return
223+
215224
for field in serializer.fields.values():
216225
if field.write_only:
217226
continue
218227

219228
child = getattr(field, "child", None)
220229

221-
if not isinstance(field, serializers.BaseSerializer) and not isinstance(
222-
child, serializers.BaseSerializer
230+
if not isinstance(
231+
field, (serializers.BaseSerializer, relations.ManyRelatedField)
232+
) and not isinstance(
233+
child, (serializers.BaseSerializer, relations.ManyRelatedField)
223234
):
224235
continue
225236

@@ -237,7 +248,11 @@ def _get_serializer_field_relations(
237248
force_prefetch = self.get_force_prefetch_data(serializer)
238249

239250
for field in self._get_fields(serializer):
240-
future_should_prefetch = should_prefetch or hasattr(field, "child")
251+
future_should_prefetch = (
252+
should_prefetch
253+
or hasattr(field, "child")
254+
or hasattr(field, "child_relation")
255+
)
241256

242257
source = getattr(field, "_prefetch_source", None) or field.source
243258

@@ -283,14 +298,33 @@ def _get_serializer_field_relations(
283298
should_prefetch=future_should_prefetch,
284299
)
285300

286-
meta = (
287-
getattr(field.child, "Meta", None)
288-
if hasattr(field, "child")
289-
else getattr(field, "Meta", None)
290-
)
301+
model = None
302+
if hasattr(field, "child"):
303+
meta = getattr(field.child, "Meta", None)
304+
elif hasattr(field, "child_relation"):
305+
meta = getattr(field.child_relation, "Meta", None)
306+
else:
307+
meta = getattr(field, "Meta", None)
308+
291309
if meta:
292310
model = getattr(meta, "model", None)
293-
if meta and model:
311+
312+
if hasattr(field, "child"):
313+
queryset = getattr(field.child, "queryset", None)
314+
elif hasattr(field, "child_relation"):
315+
queryset = getattr(field.child_relation, "queryset", None)
316+
else:
317+
queryset = getattr(field, "queryset", None)
318+
319+
if not model and queryset:
320+
model = queryset.model
321+
if isinstance(queryset, Manager):
322+
queryset = queryset.get_queryset()
323+
source = Prefetch(source, queryset)
324+
325+
print(source)
326+
327+
if model:
294328
append_to.append(source) # type: ignore
295329
select_items.extend(add_to_select)
296330
prefetch_items.extend(add_to_prefetch)

tests/test_serializers.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,3 +965,17 @@ class Meta:
965965

966966
with self.assertNumQueries(2):
967967
serializer.data
968+
969+
def test_default_id_relation(self):
970+
class ContinentSerializer(
971+
PrefetchingSerializerMixin, serializers.ModelSerializer
972+
):
973+
class Meta:
974+
model = Continent
975+
fields = ("id", "label", "country_set")
976+
977+
continents = Continent.objects.all()
978+
serializer = ContinentSerializer(continents, many=True)
979+
980+
with self.assertNumQueries(2):
981+
serializer.data

0 commit comments

Comments
 (0)