@@ -321,6 +321,29 @@ def extract_included(fields, resource, resource_instance, included_resources):
321321
322322 return utils .format_keys (included_data )
323323
324+ @staticmethod
325+ def extract_meta (serializer , resource ):
326+ if hasattr (serializer , 'child' ):
327+ meta = getattr (serializer .child , 'Meta' , None )
328+ else :
329+ meta = getattr (serializer , 'Meta' , None )
330+ meta_fields = getattr (meta , 'meta_fields' , [])
331+ data = OrderedDict ()
332+ for field_name in meta_fields :
333+ data .update ({
334+ field_name : resource .get (field_name )
335+ })
336+ return data
337+
338+ @staticmethod
339+ def extract_root_meta (serializer , resource , meta ):
340+ if getattr (serializer , 'get_root_meta' , None ):
341+ root_meta = serializer .get_root_meta (resource )
342+ if root_meta :
343+ assert isinstance (root_meta , dict ), 'get_root_meta must return a dict'
344+ meta .update (root_meta )
345+ return meta
346+
324347 @staticmethod
325348 def build_json_resource_obj (fields , resource , resource_instance , resource_name ):
326349 resource_data = [
@@ -388,6 +411,8 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
388411 included_resources = list ()
389412
390413 json_api_included = list ()
414+ # initialize json_api_meta with pagination meta or an empty dict
415+ json_api_meta = data .get ('meta' , {}) if isinstance (data , dict ) else {}
391416
392417 if data and 'results' in data :
393418 serializer_data = data ["results" ]
@@ -411,8 +436,14 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
411436 for position in range (len (serializer_data )):
412437 resource = serializer_data [position ] # Get current resource
413438 resource_instance = resource_serializer .instance [position ] # Get current instance
414- json_api_data .append (
415- self .build_json_resource_obj (fields , resource , resource_instance , resource_name ))
439+
440+ json_resource_obj = self .build_json_resource_obj (fields , resource , resource_instance , resource_name )
441+ meta = self .extract_meta (resource_serializer , resource )
442+ if meta :
443+ json_resource_obj .update ({'meta' : utils .format_keys (meta )})
444+ json_api_meta = self .extract_root_meta (resource_serializer , resource , json_api_meta )
445+ json_api_data .append (json_resource_obj )
446+
416447 included = self .extract_included (fields , resource , resource_instance , included_resources )
417448 if included :
418449 json_api_included .extend (included )
@@ -422,6 +453,12 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
422453 fields = utils .get_serializer_fields (data .serializer )
423454 resource_instance = data .serializer .instance
424455 json_api_data = self .build_json_resource_obj (fields , data , resource_instance , resource_name )
456+
457+ meta = self .extract_meta (data .serializer , data )
458+ if meta :
459+ json_api_data .update ({'meta' : utils .format_keys (meta )})
460+ json_api_meta = self .extract_root_meta (data .serializer , data , json_api_meta )
461+
425462 included = self .extract_included (fields , data , resource_instance , included_resources )
426463 if included :
427464 json_api_included .extend (included )
@@ -454,8 +491,8 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
454491 # Sort the items by type then by id
455492 render_data ['included' ] = sorted (unique_compound_documents , key = lambda item : (item ['type' ], item ['id' ]))
456493
457- if isinstance ( data , dict ) and data . get ( 'meta' ) :
458- render_data ['meta' ] = data . get ( 'meta' )
494+ if json_api_meta :
495+ render_data ['meta' ] = utils . format_keys ( json_api_meta )
459496
460497 return super (JSONRenderer , self ).render (
461498 render_data , accepted_media_type , renderer_context
0 commit comments