55from django .conf import settings
66from django .utils import six , encoding
77from django .utils .translation import ugettext_lazy as _
8- import re
98from rest_framework .serializers import BaseSerializer , ListSerializer , ModelSerializer
109from rest_framework .relations import RelatedField , HyperlinkedRelatedField , PrimaryKeyRelatedField , \
1110 HyperlinkedIdentityField
1211from rest_framework .settings import api_settings
13- from rest_framework .exceptions import APIException , ParseError
12+ from rest_framework .exceptions import APIException
1413
1514try :
1615 from rest_framework .compat import OrderedDict
@@ -190,7 +189,6 @@ def get_related_resource_type(relation):
190189
191190
192191def get_instance_or_manager_resource_type (resource_instance_or_manager ):
193-
194192 if hasattr (resource_instance_or_manager , 'model' ):
195193 return get_resource_type_from_manager (resource_instance_or_manager )
196194 if hasattr (resource_instance_or_manager , '_meta' ):
@@ -398,14 +396,14 @@ def extract_relationships(fields, resource, resource_instance):
398396def extract_included (fields , resource , resource_instance , included_resources ):
399397 included_data = list ()
400398
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 )
403402
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 ()
409407
410408 for field_name , field in six .iteritems (fields ):
411409 # Skip URL field
@@ -416,13 +414,15 @@ def extract_included(fields, resource, resource_instance, included_resources):
416414 if not isinstance (field , (RelatedField , ManyRelatedField , BaseSerializer )):
417415 continue
418416
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
421424 continue
422425
423- relation_instance_or_manager = getattr (resource_instance , field_name )
424- serializer_data = resource .get (field_name )
425-
426426 if isinstance (field , ManyRelatedField ):
427427 serializer_class = included_serializers .get (field_name )
428428 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):
450450 serializer_fields , serializer_resource , nested_resource_instance , relation_type
451451 )
452452 )
453+ included_data .extend (
454+ extract_included (
455+ serializer_fields , serializer_resource , nested_resource_instance , new_included_resources
456+ )
457+ )
453458
454459 if isinstance (field , ModelSerializer ):
455460 model = field .Meta .model
@@ -459,7 +464,13 @@ def extract_included(fields, resource, resource_instance, included_resources):
459464 serializer_fields = get_serializer_fields (field )
460465 if serializer_data :
461466 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+ )
463474 )
464475
465476 return format_keys (included_data )
0 commit comments