@@ -35,7 +35,7 @@ class PrefetchForIncludesHelperMixin(object):
35
35
36
36
def __init__ (self , * args , ** kwargs ):
37
37
warnings .warn ("PrefetchForIncludesHelperMixin is deprecated. "
38
- "Use PreloadIncludesMixin instead" ,
38
+ "Use AutoPreloadMixin instead" ,
39
39
DeprecationWarning )
40
40
super (PrefetchForIncludesHelperMixin , self ).__init__ (* args , ** kwargs )
41
41
@@ -70,7 +70,7 @@ class MyViewSet(viewsets.ModelViewSet):
70
70
return qs
71
71
72
72
73
- class PreloadIncludesMixin (object ):
73
+ class AutoPreloadMixin (object ):
74
74
"""
75
75
This mixin provides a helper attributes to select or prefetch related models
76
76
based on the include specified in the URL.
@@ -91,29 +91,31 @@ class MyViewSet(viewsets.ModelViewSet):
91
91
'author': ['author', 'author__authorbio'],
92
92
}
93
93
"""
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 )
102
94
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 )
108
97
98
+ def get_prefetch_related (self , include ):
99
+ return getattr (self , 'prefetch_for_includes' , {}).get (include , None )
109
100
110
- class AutoPreloadMixin (object ):
111
101
def get_queryset (self , * args , ** kwargs ):
112
102
""" This mixin adds automatic prefetching for OneToOne and ManyToMany fields. """
113
103
qs = super (AutoPreloadMixin , self ).get_queryset (* args , ** kwargs )
114
104
included_resources = get_included_resources (self .request )
115
105
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
117
119
included_model = None
118
120
levels = included .split ('.' )
119
121
level_model = qs .model
@@ -241,14 +243,12 @@ def get_related_instance(self):
241
243
242
244
243
245
class ModelViewSet (AutoPreloadMixin ,
244
- PreloadIncludesMixin ,
245
246
RelatedMixin ,
246
247
viewsets .ModelViewSet ):
247
248
pass
248
249
249
250
250
251
class ReadOnlyModelViewSet (AutoPreloadMixin ,
251
- PreloadIncludesMixin ,
252
252
RelatedMixin ,
253
253
viewsets .ReadOnlyModelViewSet ):
254
254
pass
0 commit comments