@@ -146,7 +146,7 @@ def format_relation_name(value, format_type=None):
146
146
def build_json_resource_obj (fields , resource , resource_instance , resource_name ):
147
147
resource_data = [
148
148
('type' , resource_name ),
149
- ('id' , extract_id ( fields , resource )),
149
+ ('id' , encoding . force_text ( resource_instance . pk )),
150
150
('attributes' , extract_attributes (fields , resource )),
151
151
]
152
152
relationships = extract_relationships (fields , resource , resource_instance )
@@ -186,31 +186,10 @@ def get_related_resource_type(relation):
186
186
return format_relation_name (relation_model .__name__ )
187
187
188
188
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
-
210
189
def extract_attributes (fields , resource ):
211
190
data = OrderedDict ()
212
191
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
214
193
if field_name == 'id' :
215
194
continue
216
195
# Skip fields with relations
@@ -234,15 +213,21 @@ def extract_relationships(fields, resource, resource_instance):
234
213
if not isinstance (field , (RelatedField , ManyRelatedField , BaseSerializer )):
235
214
continue
236
215
216
+ relation_type = get_related_resource_type (field )
217
+ relation_instance_or_manager = getattr (resource_instance , field_name )
218
+
237
219
if isinstance (field , HyperlinkedIdentityField ):
238
220
# special case for HyperlinkedIdentityField
239
221
relation_data = list ()
240
- relation_type = get_related_resource_type (field )
241
- relation_manager = getattr (resource_instance , field_name )
222
+
242
223
# 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
+ )
246
231
247
232
data .update ({field_name : {
248
233
'links' : {
@@ -255,27 +240,26 @@ def extract_relationships(fields, resource, resource_instance):
255
240
continue
256
241
257
242
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
260
244
261
245
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 )
265
249
}
266
250
267
251
relation_data .update (
268
252
{'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 ()
270
254
)
271
255
data .update ({field_name : relation_data })
272
256
continue
273
257
274
258
if isinstance (field , ManyRelatedField ):
275
259
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 ():
279
263
relation_data .append (OrderedDict ([
280
264
('type' , relation_type ),
281
265
('id' , encoding .force_text (related_object .pk ))
@@ -292,20 +276,20 @@ def extract_relationships(fields, resource, resource_instance):
292
276
293
277
if isinstance (field , ListSerializer ):
294
278
relation_data = list ()
295
-
296
279
serializer = field .child
297
280
relation_model = serializer .Meta .model
298
281
relation_type = format_relation_name (relation_model .__name__ )
299
282
300
- # Get the serializer fields
301
- serializer_fields = get_serializer_fields (serializer )
302
283
serializer_data = resource .get (field_name )
284
+ resource_instance_queryset = relation_instance_or_manager .all ()
303
285
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 ]
305
288
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
+ )
309
293
310
294
data .update ({field_name : {'data' : relation_data }})
311
295
continue
@@ -314,15 +298,12 @@ def extract_relationships(fields, resource, resource_instance):
314
298
relation_model = field .Meta .model
315
299
relation_type = format_relation_name (relation_model .__name__ )
316
300
317
- # Get the serializer fields
318
- serializer_fields = get_serializer_fields (field )
319
- serializer_data = resource .get (field_name )
320
301
data .update ({
321
302
field_name : {
322
303
'data' : (
323
304
OrderedDict ([
324
305
('type' , relation_type ),
325
- ('id' , extract_id ( serializer_fields , serializer_data ))
306
+ ('id' , encoding . force_text ( relation_instance_or_manager . pk ))
326
307
]) if resource .get (field_name ) else None )
327
308
}
328
309
})
@@ -342,38 +323,36 @@ def extract_included(fields, resource, resource_instance):
342
323
if not isinstance (field , BaseSerializer ):
343
324
continue
344
325
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 )
346
329
330
+ if isinstance (field , ListSerializer ):
347
331
serializer = field .child
348
332
model = serializer .Meta .model
349
333
relation_type = format_relation_name (model .__name__ )
350
334
351
335
# Get the serializer fields
352
336
serializer_fields = get_serializer_fields (serializer )
353
- serializer_data = resource .get (field_name )
354
- if isinstance (serializer_data , list ):
337
+ if serializer_data :
355
338
for position in range (len (serializer_data )):
356
339
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 ]
359
341
included_data .append (
360
342
build_json_resource_obj (
361
343
serializer_fields , serializer_resource , nested_resource_instance , relation_type
362
344
)
363
345
)
364
346
365
347
if isinstance (field , ModelSerializer ):
366
-
367
348
model = field .Meta .model
368
349
relation_type = format_relation_name (model .__name__ )
369
350
370
351
# Get the serializer fields
371
352
serializer_fields = get_serializer_fields (field )
372
- serializer_data = resource .get (field_name )
373
- nested_resource_instance = getattr (resource_instance , field_name ).all ()
374
353
if serializer_data :
375
354
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 )
377
356
)
378
357
379
358
return format_keys (included_data )
0 commit comments