@@ -319,6 +319,29 @@ def extract_included(fields, resource, resource_instance, included_resources):
319319
320320 return utils .format_keys (included_data )
321321
322+ @staticmethod
323+ def extract_meta (serializer , resource ):
324+ if hasattr (serializer , 'child' ):
325+ meta = getattr (serializer .child , 'Meta' , None )
326+ else :
327+ meta = getattr (serializer , 'Meta' , None )
328+ meta_fields = getattr (meta , 'meta_fields' , {})
329+ data = OrderedDict ()
330+ for field_name in meta_fields :
331+ data .update ({
332+ field_name : resource .get (field_name )
333+ })
334+ return data
335+
336+ @staticmethod
337+ def extract_root_meta (serializer , resource , meta ):
338+ if getattr (serializer , 'get_root_meta' , None ):
339+ root_meta = serializer .get_root_meta (resource )
340+ if root_meta :
341+ assert isinstance (root_meta , dict ), 'get_root_meta must return a dict'
342+ meta .update (root_meta )
343+ return meta
344+
322345 @staticmethod
323346 def build_json_resource_obj (fields , resource , resource_instance , resource_name ):
324347 resource_data = [
@@ -386,6 +409,8 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
386409 included_resources = list ()
387410
388411 json_api_included = list ()
412+ # initialize json_api_meta with pagination meta or an empty dict
413+ json_api_meta = data .get ('meta' , {}) if isinstance (data , dict ) else {}
389414
390415 if data and 'results' in data :
391416 serializer_data = data ["results" ]
@@ -409,8 +434,14 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
409434 for position in range (len (serializer_data )):
410435 resource = serializer_data [position ] # Get current resource
411436 resource_instance = resource_serializer .instance [position ] # Get current instance
412- json_api_data .append (
413- self .build_json_resource_obj (fields , resource , resource_instance , resource_name ))
437+
438+ json_resource_obj = self .build_json_resource_obj (fields , resource , resource_instance , resource_name )
439+ meta = self .extract_meta (resource_serializer , resource )
440+ if meta :
441+ json_resource_obj .update ({'meta' : utils .format_keys (meta )})
442+ json_api_meta = self .extract_root_meta (resource_serializer , resource , json_api_meta )
443+ json_api_data .append (json_resource_obj )
444+
414445 included = self .extract_included (fields , resource , resource_instance , included_resources )
415446 if included :
416447 json_api_included .extend (included )
@@ -420,6 +451,12 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
420451 fields = utils .get_serializer_fields (data .serializer )
421452 resource_instance = data .serializer .instance
422453 json_api_data = self .build_json_resource_obj (fields , data , resource_instance , resource_name )
454+
455+ meta = self .extract_meta (data .serializer , data )
456+ if meta :
457+ json_api_data .update ({'meta' : utils .format_keys (meta )})
458+ json_api_meta = self .extract_root_meta (data .serializer , data , json_api_meta )
459+
423460 included = self .extract_included (fields , data , resource_instance , included_resources )
424461 if included :
425462 json_api_included .extend (included )
@@ -452,8 +489,8 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
452489 # Sort the items by type then by id
453490 render_data ['included' ] = sorted (unique_compound_documents , key = lambda item : (item ['type' ], item ['id' ]))
454491
455- if isinstance ( data , dict ) and data . get ( 'meta' ) :
456- render_data ['meta' ] = data . get ( 'meta' )
492+ if json_api_meta :
493+ render_data ['meta' ] = utils . format_keys ( json_api_meta )
457494
458495 return super (JSONRenderer , self ).render (
459496 render_data , accepted_media_type , renderer_context
0 commit comments