5
5
from django .conf import settings
6
6
from django .utils import six , encoding
7
7
from django .utils .translation import ugettext_lazy as _
8
- import re
9
8
from rest_framework .serializers import BaseSerializer , ListSerializer , ModelSerializer
10
9
from rest_framework .relations import RelatedField , HyperlinkedRelatedField , PrimaryKeyRelatedField , \
11
10
HyperlinkedIdentityField
12
11
from rest_framework .settings import api_settings
13
- from rest_framework .exceptions import APIException , ParseError
12
+ from rest_framework .exceptions import APIException
14
13
15
14
try :
16
15
from rest_framework .compat import OrderedDict
@@ -190,7 +189,6 @@ def get_related_resource_type(relation):
190
189
191
190
192
191
def get_instance_or_manager_resource_type (resource_instance_or_manager ):
193
-
194
192
if hasattr (resource_instance_or_manager , 'model' ):
195
193
return get_resource_type_from_manager (resource_instance_or_manager )
196
194
if hasattr (resource_instance_or_manager , '_meta' ):
@@ -398,14 +396,14 @@ def extract_relationships(fields, resource, resource_instance):
398
396
def extract_included (fields , resource , resource_instance , included_resources ):
399
397
included_data = list ()
400
398
401
- context = fields .serializer .context
402
- included_serializers = getattr (context ['view' ], 'included_serializers' , None )
399
+ current_serializer = fields .serializer
400
+ context = current_serializer .context
401
+ included_serializers = getattr (fields .serializer , 'included_serializers' , None )
403
402
404
- for resource_name in included_resources :
405
- # we do not support inclusion of resources in a path
406
- match = re .search (r'\.' , resource_name )
407
- if match is not None :
408
- raise ParseError ('This endpoint does not support inclusion of resources from a path' )
403
+ included_serializers = {
404
+ key : current_serializer .__class__ if serializer == 'self' else serializer
405
+ for key , serializer in included_serializers .items ()
406
+ } if included_serializers else dict ()
409
407
410
408
for field_name , field in six .iteritems (fields ):
411
409
# Skip URL field
@@ -416,13 +414,15 @@ def extract_included(fields, resource, resource_instance, included_resources):
416
414
if not isinstance (field , (RelatedField , ManyRelatedField , BaseSerializer )):
417
415
continue
418
416
419
- # Skip fields not in requested included resources
420
- if field_name not in included_resources :
417
+ try :
418
+ included_resources .remove (field_name )
419
+ relation_instance_or_manager = getattr (resource_instance , field_name )
420
+ serializer_data = resource .get (field_name )
421
+ new_included_resources = [key .replace ('%s.' % field_name , '' , 1 ) for key in included_resources ]
422
+ except ValueError :
423
+ # Skip fields not in requested included resources
421
424
continue
422
425
423
- relation_instance_or_manager = getattr (resource_instance , field_name )
424
- serializer_data = resource .get (field_name )
425
-
426
426
if isinstance (field , ManyRelatedField ):
427
427
serializer_class = included_serializers .get (field_name )
428
428
field = serializer_class (relation_instance_or_manager .all (), many = True , context = context )
@@ -450,6 +450,11 @@ def extract_included(fields, resource, resource_instance, included_resources):
450
450
serializer_fields , serializer_resource , nested_resource_instance , relation_type
451
451
)
452
452
)
453
+ included_data .extend (
454
+ extract_included (
455
+ serializer_fields , serializer_resource , nested_resource_instance , new_included_resources
456
+ )
457
+ )
453
458
454
459
if isinstance (field , ModelSerializer ):
455
460
model = field .Meta .model
@@ -459,7 +464,13 @@ def extract_included(fields, resource, resource_instance, included_resources):
459
464
serializer_fields = get_serializer_fields (field )
460
465
if serializer_data :
461
466
included_data .append (
462
- build_json_resource_obj (serializer_fields , serializer_data , relation_instance_or_manager , relation_type )
467
+ build_json_resource_obj (serializer_fields , serializer_data , relation_instance_or_manager ,
468
+ relation_type )
469
+ )
470
+ included_data .extend (
471
+ extract_included (
472
+ serializer_fields , serializer_data , relation_instance_or_manager , new_included_resources
473
+ )
463
474
)
464
475
465
476
return format_keys (included_data )
0 commit comments