99from django .utils .six .moves .urllib .parse import urlparse , urlunparse
1010from django .utils .translation import ugettext_lazy as _
1111
12- from rest_framework .serializers import BaseSerializer
12+ from rest_framework .serializers import BaseSerializer , ListSerializer
1313from rest_framework .relations import RelatedField , HyperlinkedRelatedField
1414from rest_framework .settings import api_settings
1515from rest_framework .exceptions import APIException
@@ -50,15 +50,11 @@ def get_resource_name(context):
5050 except AttributeError :
5151 try :
5252 # Check the meta class
53- resource_name = (
54- getattr (view , 'serializer_class' )
55- .Meta .resource_name )
53+ resource_name = (getattr (view , 'serializer_class' ).Meta .resource_name )
5654 except AttributeError :
5755 # Use the model
5856 try :
59- resource_name = (
60- getattr (view , 'serializer_class' )
61- .Meta .model .__name__ )
57+ resource_name = (getattr (view , 'serializer_class' ).Meta .model .__name__ )
6258 except AttributeError :
6359 try :
6460 resource_name = view .model .__name__
@@ -82,6 +78,13 @@ def get_resource_name(context):
8278 return resource_name
8379
8480
81+ def get_serializer_fields (serializer ):
82+ if hasattr (serializer , 'child' ):
83+ return getattr (serializer .child , 'fields' )
84+ else :
85+ return getattr (serializer , 'fields' )
86+
87+
8588def format_keys (obj , format_type = None ):
8689 """
8790 Takes either a dict or list and returns it with camelized keys only if
@@ -127,7 +130,7 @@ def build_root(fields, resource, resource_name):
127130 # Add 'self' link if field is present and valid
128131 if api_settings .URL_FIELD_NAME in resource and \
129132 isinstance (fields [api_settings .URL_FIELD_NAME ], RelatedField ):
130- resource_data .append (('links' , {'self' : resource [api_settings .URL_FIELD_NAME ]}))
133+ resource_data .append (('links' , {'self' : resource [api_settings .URL_FIELD_NAME ]}))
131134 return OrderedDict (resource_data )
132135
133136
@@ -192,3 +195,40 @@ def extract_relationships(fields, resource):
192195 data .update ({field_name : {'data' : relation_data }})
193196
194197 return format_keys (data )
198+
199+
200+ def extract_included (fields , resource ):
201+ included_data = list ()
202+ for field_name , field in six .iteritems (fields ):
203+ # Skip URL field
204+ if field_name == api_settings .URL_FIELD_NAME :
205+ continue
206+
207+ # Skip fields without serialized data
208+ if not isinstance (field , BaseSerializer ):
209+ continue
210+
211+ if isinstance (field , ListSerializer ):
212+
213+ serializer = field .child
214+ model = serializer .Meta .model
215+ relation_type = inflection .pluralize (model .__name__ ).lower ()
216+
217+ # Get the serializer fields
218+ serializer_fields = get_serializer_fields (serializer )
219+ serializer_data = resource [field_name ]
220+ if isinstance (serializer_data , list ):
221+ for serializer_resource in serializer_data :
222+ resource_data = [
223+ ('type' , relation_type ),
224+ ('id' , extract_id (serializer_fields , serializer_resource )),
225+ ('attributes' , extract_attributes (serializer_fields , serializer_resource )),
226+ ('relationships' , extract_relationships (serializer_fields , serializer_resource )),
227+ ]
228+ # Add 'self' link if field is present and valid
229+ if api_settings .URL_FIELD_NAME in serializer_resource and \
230+ isinstance (serializer_fields [api_settings .URL_FIELD_NAME ], RelatedField ):
231+ resource_data .append (('links' , {'self' : serializer_resource [api_settings .URL_FIELD_NAME ]}))
232+ included_data .append (OrderedDict (resource_data ))
233+
234+ return format_keys (included_data )
0 commit comments