@@ -35,7 +35,7 @@ class PrefetchForIncludesHelperMixin(object):
3535
3636 def __init__ (self , * args , ** kwargs ):
3737 warnings .warn ("PrefetchForIncludesHelperMixin is deprecated. "
38- "Use PreloadIncludesMixin instead" ,
38+ "Use AutoPreloadMixin instead" ,
3939 DeprecationWarning )
4040 super (PrefetchForIncludesHelperMixin , self ).__init__ (* args , ** kwargs )
4141
@@ -70,7 +70,7 @@ class MyViewSet(viewsets.ModelViewSet):
7070 return qs
7171
7272
73- class PreloadIncludesMixin (object ):
73+ class AutoPreloadMixin (object ):
7474 """
7575 This mixin provides a helper attributes to select or prefetch related models
7676 based on the include specified in the URL.
@@ -91,29 +91,31 @@ class MyViewSet(viewsets.ModelViewSet):
9191 'author': ['author', 'author__authorbio'],
9292 }
9393 """
94- def get_queryset (self ):
95- qs = super (PreloadIncludesMixin , self ).get_queryset ()
96-
97- includes = self .request .GET .get ('include' , '' ).split (',' ) + ['__all__' ]
98-
99- if hasattr (self , 'select_for_includes' ):
100- selects = [self .select_for_includes .get (inc ) for inc in includes ]
101- qs = qs .select_related (* selects )
10294
103- if hasattr (self , 'prefetch_for_includes' ):
104- prefetches = [self .prefetch_for_includes .get (inc ) for inc in includes ]
105- qs = qs .prefetch_related (* prefetches )
106-
107- return qs
95+ def get_select_related (self , include ):
96+ return getattr (self , 'select_for_includes' , {}).get (include , None )
10897
98+ def get_prefetch_related (self , include ):
99+ return getattr (self , 'prefetch_for_includes' , {}).get (include , None )
109100
110- class AutoPreloadMixin (object ):
111101 def get_queryset (self , * args , ** kwargs ):
112102 """ This mixin adds automatic prefetching for OneToOne and ManyToMany fields. """
113103 qs = super (AutoPreloadMixin , self ).get_queryset (* args , ** kwargs )
114104 included_resources = get_included_resources (self .request )
115105
116- for included in included_resources :
106+ for included in included_resources + ['__all__' ]:
107+ # Custom defined "select_related" and "prefetch_related" is a priority
108+ select_related = self .get_select_related (included )
109+ if select_related is not None :
110+ qs = qs .select_related (* select_related )
111+ continue
112+
113+ prefetch_related = self .get_prefetch_related (included )
114+ if prefetch_related is not None :
115+ qs = qs .prefetch_related (* prefetch_related )
116+ continue
117+
118+ # If include was not defined, trying to resolve it automatically
117119 included_model = None
118120 levels = included .split ('.' )
119121 level_model = qs .model
@@ -241,14 +243,12 @@ def get_related_instance(self):
241243
242244
243245class ModelViewSet (AutoPreloadMixin ,
244- PreloadIncludesMixin ,
245246 RelatedMixin ,
246247 viewsets .ModelViewSet ):
247248 pass
248249
249250
250251class ReadOnlyModelViewSet (AutoPreloadMixin ,
251- PreloadIncludesMixin ,
252252 RelatedMixin ,
253253 viewsets .ReadOnlyModelViewSet ):
254254 pass
0 commit comments