with test modelserializer instalar framework español create django django-rest-framework

test - Agregar elemento raíz a la respuesta json(django-rest-framework)



modelserializer django rest framework (2)

Estoy tratando de determinar la mejor manera de agregar un elemento raíz a todas las respuestas json usando django y django-rest-framework.

Creo que agregar un renderizador personalizado es la mejor manera de lograr lo que quiero lograr y esto es lo que he propuesto hasta ahora:

from rest_framework.renderers import JSONRenderer class CustomJSONRenderer(JSONRenderer): #override the render method def render(self, data, accepted_media_type=None, renderer_context=None): #call super, as we really just want to mess with the data returned json_str = super(CustomJSONRenderer, self).render(data, accepted_media_type, renderer_context) root_element = ''contact'' #wrap the json string in the desired root element ret = ''{%s: %s}'' % (root_element, json_str) return ret

La parte complicada ahora es establecer dinámicamente el elemento root_element basado en la vista desde la que se llama a render() .

Cualquier sugerencia / consejos sería muy apreciada,

Aclamaciones


Para la posteridad, a continuación se encuentra la solución final. Ha crecido ligeramente desde el original, ya que ahora reformatea los resultados paginados también.

También debería haber especificado antes, que la razón para el elemento raíz JSON es para la integración con una solución de front-end Ember.

serializador

from rest_framework.serializers import ModelSerializer from api.models import Contact class ContactSerializer(ModelSerializer): class Meta: model = Contact #define the resource we wish to use for the root element of the response resource_name = ''contact'' fields = (''id'', ''first_name'', ''last_name'', ''phone_number'', ''company'')

renderizador:

from rest_framework.renderers import JSONRenderer class CustomJSONRenderer(JSONRenderer): """ Override the render method of the django rest framework JSONRenderer to allow the following: * adding a resource_name root element to all GET requests formatted with JSON * reformatting paginated results to the following structure {meta: {}, resource_name: [{},{}]} NB: This solution requires a custom pagination serializer and an attribute of ''resource_name'' defined in the serializer """ def render(self, data, accepted_media_type=None, renderer_context=None): response_data = {} #determine the resource name for this request - default to objects if not defined resource = getattr(renderer_context.get(''view'').get_serializer().Meta, ''resource_name'', ''objects'') #check if the results have been paginated if data.get(''paginated_results''): #add the resource key and copy the results response_data[''meta''] = data.get(''meta'') response_data[resource] = data.get(''paginated_results'') else: response_data[resource] = data #call super to render the response response = super(CustomJSONRenderer, self).render(response_data, accepted_media_type, renderer_context) return response

paginación:

from rest_framework import pagination, serializers class CustomMetaSerializer(serializers.Serializer): next_page = pagination.NextPageField(source=''*'') prev_page = pagination.PreviousPageField(source=''*'') record_count = serializers.Field(source=''paginator.count'') class CustomPaginationSerializer(pagination.BasePaginationSerializer): # Takes the page object as the source meta = CustomMetaSerializer(source=''*'') results_field = ''paginated_results''


Estoy seguro de poder despertarme el 95% del camino.

Personalmente, quería agregar metadatos a cada solicitud de API para un determinado objeto, independientemente de si estaba paginado o no. También quería simplemente pasar un objeto dict que definí manualmente.

Repetidor Personalizado Tweaked

class CustomJSONRenderer(renderers.JSONRenderer): def render(self, data, accepted_media_type=None, renderer_context=None): response_data = {} # Name the object list object_list = ''results'' try: meta_dict = getattr(renderer_context.get(''view'').get_serializer().Meta, ''meta_dict'') except: meta_dict = dict() try: data.get(''paginated_results'') response_data[''meta''] = data[''meta''] response_data[object_list] = data[''results''] except: response_data[object_list] = data response_data[''meta''] = dict() # Add custom meta data response_data[''meta''].update(meta_dict) # Call super to render the response response = super(CustomJSONRenderer, self).render(response_data, accepted_media_type, renderer_context) return response

Parent Serializer y ejemplo de vista

class MovieListSerializer(serializers.ModelSerializer): class Meta: model = Movie meta_dict = dict() meta_dict[''foo''] = ''bar'' class MovieViewSet(generics.ListAPIView): queryset = Movie.objects.exclude(image__exact = "") serializer_class = MovieListSerializer permission_classes = (IsAdminOrReadOnly,) renderer_classes = (CustomJSONRenderer,) pagination_serializer_class = CustomPaginationSerializer paginate_by = 10