@@ -146,7 +146,7 @@ def format_relation_name(value, format_type=None):
146146def build_json_resource_obj (fields , resource , resource_instance , resource_name ):
147147 resource_data = [
148148 ('type' , resource_name ),
149- ('id' , extract_id ( fields , resource )),
149+ ('id' , encoding . force_text ( resource_instance . pk )),
150150 ('attributes' , extract_attributes (fields , resource )),
151151 ]
152152 relationships = extract_relationships (fields , resource , resource_instance )
@@ -186,31 +186,10 @@ def get_related_resource_type(relation):
186186 return format_relation_name (relation_model .__name__ )
187187
188188
189- def extract_id_from_url (url ):
190- http_prefix = url .startswith (('http:' , 'https:' ))
191- if http_prefix :
192- # If needed convert absolute URLs to relative path
193- data = urlparse (url ).path
194- prefix = urlresolvers .get_script_prefix ()
195- if data .startswith (prefix ):
196- url = '/' + data [len (prefix ):]
197-
198- match = urlresolvers .resolve (url )
199- return encoding .force_text (match .kwargs ['pk' ])
200-
201-
202- def extract_id (fields , resource ):
203- for field_name , field in six .iteritems (fields ):
204- if field_name == 'id' :
205- return encoding .force_text (resource .get (field_name ))
206- if field_name == api_settings .URL_FIELD_NAME :
207- return extract_id_from_url (resource .get (field_name ))
208-
209-
210189def extract_attributes (fields , resource ):
211190 data = OrderedDict ()
212191 for field_name , field in six .iteritems (fields ):
213- # ID is always provided in the root of JSON API so remove it from attrs
192+ # ID is always provided in the root of JSON API so remove it from attributes
214193 if field_name == 'id' :
215194 continue
216195 # Skip fields with relations
@@ -234,15 +213,21 @@ def extract_relationships(fields, resource, resource_instance):
234213 if not isinstance (field , (RelatedField , ManyRelatedField , BaseSerializer )):
235214 continue
236215
216+ relation_type = get_related_resource_type (field )
217+ relation_instance_or_manager = getattr (resource_instance , field_name )
218+
237219 if isinstance (field , HyperlinkedIdentityField ):
238220 # special case for HyperlinkedIdentityField
239221 relation_data = list ()
240- relation_type = get_related_resource_type (field )
241- relation_manager = getattr (resource_instance , field_name )
222+
242223 # Don't try to query an empty relation
243- related = relation_manager .all () if relation_manager is not None else list ()
244- for relation in related :
245- relation_data .append (OrderedDict ([('type' , relation_type ), ('id' , relation .pk )]))
224+ relation_queryset = relation_instance_or_manager .all () \
225+ if relation_instance_or_manager is not None else list ()
226+
227+ for related_object in relation_queryset :
228+ relation_data .append (
229+ OrderedDict ([('type' , relation_type ), ('id' , encoding .force_text (related_object .pk ))])
230+ )
246231
247232 data .update ({field_name : {
248233 'links' : {
@@ -255,27 +240,26 @@ def extract_relationships(fields, resource, resource_instance):
255240 continue
256241
257242 if isinstance (field , (PrimaryKeyRelatedField , HyperlinkedRelatedField )):
258- relation_type = get_related_resource_type (field )
259- relation_id = getattr (resource_instance , field_name ).pk if resource .get (field_name ) else None
243+ relation_id = relation_instance_or_manager .pk if resource .get (field_name ) else None
260244
261245 relation_data = {
262- 'data' : (OrderedDict ([
263- ( 'type' , relation_type ), ('id' , relation_id )
264- ]) if relation_id is not None else None )
246+ 'data' : (
247+ OrderedDict ([( 'type' , relation_type ), ('id' , encoding . force_text ( relation_id ))] )
248+ if relation_id is not None else None )
265249 }
266250
267251 relation_data .update (
268252 {'links' : {'related' : resource .get (field_name )}}
269- if isinstance (field , HyperlinkedRelatedField ) and resource .get (field_name ) else {}
253+ if isinstance (field , HyperlinkedRelatedField ) and resource .get (field_name ) else dict ()
270254 )
271255 data .update ({field_name : relation_data })
272256 continue
273257
274258 if isinstance (field , ManyRelatedField ):
275259 relation_data = list ()
276- relation = field .child_relation
277- relation_type = get_related_resource_type (relation )
278- for related_object in getattr ( resource_instance , field_name ) .all ():
260+ related_object = field .child_relation
261+ relation_type = get_related_resource_type (related_object )
262+ for related_object in relation_instance_or_manager .all ():
279263 relation_data .append (OrderedDict ([
280264 ('type' , relation_type ),
281265 ('id' , encoding .force_text (related_object .pk ))
@@ -292,20 +276,20 @@ def extract_relationships(fields, resource, resource_instance):
292276
293277 if isinstance (field , ListSerializer ):
294278 relation_data = list ()
295-
296279 serializer = field .child
297280 relation_model = serializer .Meta .model
298281 relation_type = format_relation_name (relation_model .__name__ )
299282
300- # Get the serializer fields
301- serializer_fields = get_serializer_fields (serializer )
302283 serializer_data = resource .get (field_name )
284+ resource_instance_queryset = relation_instance_or_manager .all ()
303285 if isinstance (serializer_data , list ):
304- for serializer_resource in serializer_data :
286+ for position in range (len (serializer_data )):
287+ nested_resource_instance = resource_instance_queryset [position ]
305288 relation_data .append (
306- OrderedDict ([
307- ('type' , relation_type ), ('id' , extract_id (serializer_fields , serializer_resource ))
308- ]))
289+ OrderedDict (
290+ [('type' , relation_type ), ('id' , encoding .force_text (nested_resource_instance .pk ))]
291+ )
292+ )
309293
310294 data .update ({field_name : {'data' : relation_data }})
311295 continue
@@ -314,15 +298,12 @@ def extract_relationships(fields, resource, resource_instance):
314298 relation_model = field .Meta .model
315299 relation_type = format_relation_name (relation_model .__name__ )
316300
317- # Get the serializer fields
318- serializer_fields = get_serializer_fields (field )
319- serializer_data = resource .get (field_name )
320301 data .update ({
321302 field_name : {
322303 'data' : (
323304 OrderedDict ([
324305 ('type' , relation_type ),
325- ('id' , extract_id ( serializer_fields , serializer_data ))
306+ ('id' , encoding . force_text ( relation_instance_or_manager . pk ))
326307 ]) if resource .get (field_name ) else None )
327308 }
328309 })
@@ -342,38 +323,36 @@ def extract_included(fields, resource, resource_instance):
342323 if not isinstance (field , BaseSerializer ):
343324 continue
344325
345- if isinstance (field , ListSerializer ):
326+ relation_instance_or_manager = getattr (resource_instance , field_name )
327+ relation_queryset = relation_instance_or_manager .all ()
328+ serializer_data = resource .get (field_name )
346329
330+ if isinstance (field , ListSerializer ):
347331 serializer = field .child
348332 model = serializer .Meta .model
349333 relation_type = format_relation_name (model .__name__ )
350334
351335 # Get the serializer fields
352336 serializer_fields = get_serializer_fields (serializer )
353- serializer_data = resource .get (field_name )
354- if isinstance (serializer_data , list ):
337+ if serializer_data :
355338 for position in range (len (serializer_data )):
356339 serializer_resource = serializer_data [position ]
357- resource_instance_manager = getattr (resource_instance , field_name ).all ()
358- nested_resource_instance = resource_instance_manager [position ]
340+ nested_resource_instance = relation_queryset [position ]
359341 included_data .append (
360342 build_json_resource_obj (
361343 serializer_fields , serializer_resource , nested_resource_instance , relation_type
362344 )
363345 )
364346
365347 if isinstance (field , ModelSerializer ):
366-
367348 model = field .Meta .model
368349 relation_type = format_relation_name (model .__name__ )
369350
370351 # Get the serializer fields
371352 serializer_fields = get_serializer_fields (field )
372- serializer_data = resource .get (field_name )
373- nested_resource_instance = getattr (resource_instance , field_name ).all ()
374353 if serializer_data :
375354 included_data .append (
376- build_json_resource_obj (serializer_fields , serializer_data , nested_resource_instance , relation_type )
355+ build_json_resource_obj (serializer_fields , serializer_data , relation_queryset , relation_type )
377356 )
378357
379358 return format_keys (included_data )
0 commit comments