@@ -36,6 +36,12 @@ def get_additional_serializers_data(self, serializer):
3636
3737 return getattr (serializer , "additional_serializers" , [])
3838
39+ def get_force_prefetch_data (self , serializer ):
40+ if hasattr (serializer , "get_force_prefetch" ):
41+ return serializer .get_force_prefetch ()
42+
43+ return getattr (serializer , "force_prefetch" , [])
44+
3945 def other_prefetching (self ):
4046 """
4147 Override this method to add additional prefetching that
@@ -83,8 +89,9 @@ def get_prefetch(
8389 if hasattr (serializer , "child" ):
8490 serializer = serializer .child
8591
92+ force_prefetch = self .get_force_prefetch_data (serializer )
8693 select_items , prefetch_items = self ._get_custom_relations (
87- serializer , current_relation
94+ serializer , current_relation , force_prefetch = force_prefetch
8895 )
8996 self ._extend_relation_items (
9097 select_items ,
@@ -127,10 +134,17 @@ def _extend_relation_items(
127134
128135 return select_items , prefetch_items
129136
130- def _get_custom_relations (self , serializer , current_relation ):
131- select_related_attr = self .get_select_related_data (serializer )
137+ def _get_custom_relations (self , serializer , current_relation , * , force_prefetch = ()):
138+ select_related_attr = []
139+ temp_select_related_attr = self .get_select_related_data (serializer )
132140 prefetch_related_attr = self .get_prefetch_related_data (serializer )
133141
142+ for select in temp_select_related_attr :
143+ if select in force_prefetch :
144+ prefetch_related_attr .append (select )
145+ else :
146+ select_related_attr .append (select )
147+
134148 custom_select_related = (
135149 self ._get_custom_related (select_related_attr , current_relation ) or []
136150 )
@@ -202,6 +216,7 @@ def _get_serializer_field_relations(
202216 return select_items , prefetch_items
203217
204218 info = model_meta .get_field_info (model )
219+ force_prefetch = self .get_force_prefetch_data (serializer )
205220
206221 for field in serializer .fields .values ():
207222 if field .write_only :
@@ -223,7 +238,11 @@ def _get_serializer_field_relations(
223238 if relation .to_many :
224239 future_should_prefetch = True
225240
226- append_to = prefetch_items if future_should_prefetch else select_items
241+ append_to = (
242+ prefetch_items
243+ if future_should_prefetch or source in force_prefetch
244+ else select_items
245+ )
227246
228247 if should_prefetch :
229248 source = Prefetch (source )
@@ -331,19 +350,10 @@ def to_representation(self, instance, *args, **kwargs):
331350 child = self .child
332351 select_items , prefetch_items = self .get_prefetch (child )
333352
334- prefetch_has_prefetch_objects = any (
335- isinstance (p , Prefetch ) and p .prefetch_to != p .prefetch_through
336- for p in prefetch_items
337- )
338-
339353 if isinstance (instance , QuerySet ):
340- instance = instance .prefetch_related (
341- * self .get_ordered_prefetches (prefetch_items )
342- )
343- if not prefetch_has_prefetch_objects :
354+ if select_items :
344355 instance = instance .select_related (* select_items )
345- else :
346- instance = instance .prefetch_related (* select_items )
356+ instance = instance .prefetch_related (* prefetch_items )
347357 instance = self .queryset_after_prefetch (instance )
348358
349359 else :
@@ -385,9 +395,7 @@ def to_representation(self, instance, *args, **kwargs):
385395 ):
386396 select_items , prefetch_items = self .get_prefetch (self )
387397
388- for related_lookup in (
389- list (self .get_ordered_prefetches (prefetch_items )) + select_items
390- ):
398+ for related_lookup in select_items + prefetch_items :
391399 try :
392400 prefetch_related_objects ([instance ], related_lookup )
393401 except AttributeError as exc :
0 commit comments