1- from __future__ import unicode_literals
2-
3- import six
41import copy
5-
62from itertools import chain
73
84from django .db .models import Prefetch
@@ -31,9 +27,7 @@ def __init__(self, **kwargs):
3127 def check_sideloading_serializer_class (self ):
3228 assert (
3329 self .sideloading_serializer_class is not None
34- ), "'{}' should either include a `sideloading_serializer_class` attribute, " .format (
35- self .__class__ .__name__
36- )
30+ ), "'{}' should either include a `sideloading_serializer_class` attribute, " .format (self .__class__ .__name__ )
3731 assert issubclass (
3832 self .sideloading_serializer_class , SideLoadableSerializer
3933 ), "'{}' `sideloading_serializer_class` must be a SideLoadableSerializer subclass" .format (
@@ -51,36 +45,26 @@ def check_sideloading_serializer_class(self):
5145 self .sideloading_serializer_class .Meta , "primary" , None
5246 ), "Sideloadable serializer must have a Meta attribute called primary!"
5347 assert (
54- self .sideloading_serializer_class .Meta .primary
55- in self .sideloading_serializer_class ._declared_fields
48+ self .sideloading_serializer_class .Meta .primary in self .sideloading_serializer_class ._declared_fields
5649 ), "Sideloadable serializer Meta.primary must point to a field in the serializer!"
57- if (
58- getattr (self .sideloading_serializer_class .Meta , "prefetches" , None )
59- is not None
60- ):
50+ if getattr (self .sideloading_serializer_class .Meta , "prefetches" , None ) is not None :
6151 assert isinstance (
6252 self .sideloading_serializer_class .Meta .prefetches , dict
6353 ), "Sideloadable serializer Meta attribute 'prefetches' must be a dict."
6454
6555 # check serializer fields:
6656 for name , field in self .sideloading_serializer_class ._declared_fields .items ():
67- assert getattr (
68- field , "many" , None
69- ), "SideLoadable field '{}' must be set as many=True" .format (name )
57+ assert getattr (field , "many" , None ), "SideLoadable field '{}' must be set as many=True" .format (name )
7058
7159 # check serializer fields:
7260 for name , field in self .sideloading_serializer_class ._declared_fields .items ():
73- assert getattr (
74- field , "many" , None
75- ), "SideLoadable field '{}' must be set as many=True" .format (name )
61+ assert getattr (field , "many" , None ), "SideLoadable field '{}' must be set as many=True" .format (name )
7662
7763 def get_primary_field_name (self ):
7864 return self .sideloading_serializer_class .Meta .primary
7965
8066 def get_sideloadable_fields (self ):
81- sideloadable_fields = copy .deepcopy (
82- self .sideloading_serializer_class ._declared_fields
83- )
67+ sideloadable_fields = copy .deepcopy (self .sideloading_serializer_class ._declared_fields )
8468 sideloadable_fields .pop (self ._primary_field_name , None )
8569 return sideloadable_fields
8670
@@ -94,44 +78,33 @@ def get_sideloading_prefetches(self):
9478 if not isinstance (v , list ):
9579 v = [v ]
9680 for vi in v :
97- if not isinstance (vi , (six . string_types , Prefetch )):
81+ if not isinstance (vi , (str , Prefetch )):
9882 raise RuntimeError ("Sideloadable prefetch values must be a list of strings or Prefetch objects" )
9983 return cleaned_prefetches
10084
10185 def initialize_request (self , request , * args , ** kwargs ):
102- request = super (SideloadableRelationsMixin , self ).initialize_request (
103- request = request , * args , ** kwargs
104- )
86+ request = super (SideloadableRelationsMixin , self ).initialize_request (request = request , * args , ** kwargs )
10587
106- sideload_params = self .parse_query_param (
107- sideload_parameter = request .query_params .get (self .query_param_name , "" )
108- )
88+ sideload_params = self .parse_query_param (sideload_parameter = request .query_params .get (self .query_param_name , "" ))
10989 if request .method == "GET" and sideload_params :
11090 # When sideloading disable BrowsableAPIForms
11191 if BrowsableAPIRenderer in self .renderer_classes :
11292 renderer_classes = (
113- list (self .renderer_classes )
114- if isinstance (self .renderer_classes , tuple )
115- else self .renderer_classes
93+ list (self .renderer_classes ) if isinstance (self .renderer_classes , tuple ) else self .renderer_classes
11694 )
11795 renderer_classes = [
118- BrowsableAPIRendererWithoutForms if r == BrowsableAPIRenderer else r
119- for r in renderer_classes
96+ BrowsableAPIRendererWithoutForms if r == BrowsableAPIRenderer else r for r in renderer_classes
12097 ]
12198 self .renderer_classes = renderer_classes
12299
123100 return request
124101
125102 def list (self , request , * args , ** kwargs ):
126- sideload_params = self .parse_query_param (
127- sideload_parameter = request .query_params .get (self .query_param_name , "" )
128- )
103+ sideload_params = self .parse_query_param (sideload_parameter = request .query_params .get (self .query_param_name , "" ))
129104
130105 # Do not sideload unless params and GET method
131106 if request .method != "GET" or not sideload_params :
132- return super (SideloadableRelationsMixin , self ).list (
133- request , * args , ** kwargs
134- )
107+ return super (SideloadableRelationsMixin , self ).list (request , * args , ** kwargs )
135108
136109 # After this `relations_to_sideload` is safe to use
137110 queryset = self .get_queryset ()
@@ -148,17 +121,15 @@ def list(self, request, *args, **kwargs):
148121 sideloadable_page = self .get_sideloadable_page (page )
149122 serializer = self .sideloading_serializer_class (
150123 instance = sideloadable_page ,
151- fields_to_load = [self ._primary_field_name ]
152- + list (self .relations_to_sideload ),
124+ fields_to_load = [self ._primary_field_name ] + list (self .relations_to_sideload ),
153125 context = {"request" : request },
154126 )
155127 return self .get_paginated_response (serializer .data )
156128 else :
157129 sideloadable_page = self .get_sideloadable_page_from_queryset (queryset )
158130 serializer = self .sideloading_serializer_class (
159131 instance = sideloadable_page ,
160- fields_to_load = [self ._primary_field_name ]
161- + list (self .relations_to_sideload ),
132+ fields_to_load = [self ._primary_field_name ] + list (self .relations_to_sideload ),
162133 context = {"request" : request },
163134 )
164135 return Response (serializer .data )
@@ -174,67 +145,45 @@ def parse_query_param(self, sideload_parameter):
174145 This function finds string match between requested names and defined relation in view
175146
176147 """
177- self .relations_to_sideload = set (sideload_parameter .split ("," )) & set (
178- self ._sideloadable_fields .keys ()
179- )
148+ self .relations_to_sideload = set (sideload_parameter .split ("," )) & set (self ._sideloadable_fields .keys ())
180149 return self .relations_to_sideload
181150
182151 def get_relevant_prefetches (self ):
183152 if not self ._prefetches :
184153 return set ()
185- return set (
186- pf
187- for relation in self .relations_to_sideload
188- for pf in self ._prefetches .get (relation , [])
189- )
154+ return set (pf for relation in self .relations_to_sideload for pf in self ._prefetches .get (relation , []))
190155
191156 def get_sideloadable_page_from_queryset (self , queryset ):
192157 # this works wonders, but can't be used when page is paginated...
193158 sideloadable_page = {self ._primary_field_name : queryset }
194159 for relation in self .relations_to_sideload :
195160 if not isinstance (self ._sideloadable_fields [relation ], ListSerializer ):
196- raise RuntimeError (
197- "SideLoadable field '{}' must be set as many=True" .format (relation )
198- )
161+ raise RuntimeError ("SideLoadable field '{}' must be set as many=True" .format (relation ))
199162
200163 source = self ._sideloadable_fields [relation ].source or relation
201164 rel_model = self ._sideloadable_fields [relation ].child .Meta .model
202- rel_qs = rel_model .objects .filter (
203- pk__in = queryset .values_list (source , flat = True )
204- )
165+ rel_qs = rel_model .objects .filter (pk__in = queryset .values_list (source , flat = True ))
205166 sideloadable_page [source ] = rel_qs
206167 return sideloadable_page
207168
208169 def get_sideloadable_page (self , page ):
209170 sideloadable_page = {self ._primary_field_name : page }
210171 for relation in self .relations_to_sideload :
211172 if not isinstance (self ._sideloadable_fields [relation ], ListSerializer ):
212- raise RuntimeError (
213- "SideLoadable field '{}' must be set as many=True" .format (relation )
214- )
173+ raise RuntimeError ("SideLoadable field '{}' must be set as many=True" .format (relation ))
215174
216175 source = self ._sideloadable_fields [relation ].source or relation
217- sideloadable_page [source ] = self .filter_related_objects (
218- related_objects = page , lookup = source
219- )
176+ sideloadable_page [source ] = self .filter_related_objects (related_objects = page , lookup = source )
220177 return sideloadable_page
221178
222179 def filter_related_objects (self , related_objects , lookup ):
223- current_lookup , remaining_lookup = (
224- lookup .split ("__" , 1 ) if "__" in lookup else (lookup , None )
225- )
180+ current_lookup , remaining_lookup = lookup .split ("__" , 1 ) if "__" in lookup else (lookup , None )
226181 related_objects_set = {getattr (r , current_lookup ) for r in related_objects } - {None }
227- if related_objects_set and next (
228- iter (related_objects_set )
229- ).__class__ .__name__ in ["ManyRelatedManager" , "RelatedManager" ]:
230- related_objects_set = set (
231- chain (
232- * [
233- related_queryset .all ()
234- for related_queryset in related_objects_set
235- ]
236- )
237- )
182+ if related_objects_set and next (iter (related_objects_set )).__class__ .__name__ in [
183+ "ManyRelatedManager" ,
184+ "RelatedManager" ,
185+ ]:
186+ related_objects_set = set (chain (* [related_queryset .all () for related_queryset in related_objects_set ]))
238187 if remaining_lookup :
239188 return self .filter_related_objects (related_objects_set , remaining_lookup )
240189 return set (related_objects_set ) - {"" , None }
0 commit comments