Cómo obtener una respuesta de varios objetos utilizando rest_framework y Django

Soy nuevo en el framework Django y el framework REST de Django, pero tengo la configuración básica y la implementación en ejecución. Funciona como un encanto cuando llamo al dominio para objetos individuales, por ejemplo, http://mydomain.com/location/1 (donde 1 es la clave principal). Esto me da la respuesta JSON como:

{"id": 1, "location": "Berlin", "country": 2} 

.. y http://mydomain.com/country/2 respuestas como:

 {"id": 2, "country": "Germany"} 

Lo que necesito: ahora necesito obtener varias ubicaciones, por ejemplo, al llamar al dominio http://mydomain.com/all_locations/ . Yo esperaría una respuesta como:

 [ {"id": 1, "location": "Berlin", "country": 2}, {"id": 2, "location": "New York", "country": 4}, {"id": 3, "location": "Barcelona", "country": 5}, {"id": 4, "location": "Moscow", "country": 7} ] 

Esto es opcional: en un segundo paso, me encantaría tener varios países y ubicaciones en una respuesta cuando llamo http://mydomain.com/mix_all_locations_countries/ , por ejemplo:

 [ {"locations": {"id": 1, "location": "Berlin", "country": 2}, {"id": 2, "location": "New York", "country": 4}, {"id": 3, "location": "Barcelona", "country": 5}, {"id": 4, "location": "Moscow", "country": 7} }, {"countries": {"id": 1, "country": "Brazil"} {"id": 2, "country": "Germany"}, {"id": 3, "country": "Portugual"} {"id": 4, "country": "USA"}, {"id": 5, "country": "Spain"}, {"id": 6, "country": "Italy"} {"id": 7, "country": "Russia"} } ] 

Aquí está mi implementación hasta ahora (solo muestra la implementación de la ubicación):

en modelos.py :

 class Location(models.Model): # variable id and pk are always available location = models.CharField(max_length=100) country = models.ForeignKey("Country") 

en serializers.py :

 class LocationsSerializer(serializers.ModelSerializer): country_id = serializers.Field(source='country.id') class Meta: model = Location fields = ( 'id', 'location', 'country_id', ) 

en views.py :

 class LocationAPIView(generics.RetrieveAPIView): queryset = Location.objects.all() serializer_class = LocationSerializer 

en urls.py :

 url(r'^location/(?P[0-9]+)/$', views.LocationAPIView.as_view(), name='LocationAPIView') 

Lo que intenté: creo que no necesito modificar el modelo y el serializador, porque funciona para objetos individuales al llamar al dominio mencionado anteriormente. Así que intenté implementar un LocationsViewSet en views.py y agregué una nueva url en urls.py , pero fallé. ¿Alguna idea de cómo podría implementarlo? Tal vez solo defina un método en LocationAPIView y cambie defina una url similar a esto:

 url(r'^all_locations/$', views.LocationAPIView.get_all_locations(), name='LocationAPIView') 

Gracias de antemano, agradeceré cualquier ayuda.

Saludos cordiales michael

En primer lugar, solo olvidemos los conjuntos de imágenes por el momento: hacen algunas cosas más simples, pero también introducen una capa extra de abstracción que no creo que debas preocuparte en este momento.

Lo primero que menciona que necesita es un punto final de lista equivalente a su punto final de detalle actual. Ya lo tienes, solo necesitas introducir una vista adicional junto con la vista existente.

views.py :

 class LocationListAPIView(generics.ListAPIView): queryset = Location.objects.all() serializer_class = LocationSerializer class LocationDetailAPIView(generics.RetrieveAPIView): queryset = Location.objects.all() serializer_class = LocationSerializer 

Ahora conecta ambas vistas en tu URLconf.

urls.py :

 url(r'^location/$', views.LocationListAPIView.as_view(), name='location-list'), url(r'^location/(?P[0-9]+)/$', views.LocationDetailAPIView.as_view(), name='location-detail') 

Tenga en cuenta que también he cambiado el estilo del nombre de la URL para que sea más estándar con las convenciones habituales de Django.

A continuación, querías una ubicación combinada + vista de países. No solo podrás usar una vista genérica existente ya que es un comportamiento bastante personalizado, pero es bastante fácil escribir una vista para …

views.py :

 class CombinedAPIView(APIView): def get(self, request): locations = Location.objects.all() countries = Country.objects.all() location_serializer = LocationSerializer(locations, many=True) country_serializer = CountrySerializer(countries, many=True) return Response({ 'countries': country_serializer.data, 'locations': location_serializer.data }) 

Y cablea la vista hacia arriba.

urls.py :

 url(r'^combined/$', views.CombinedAPIView.as_view(), name='combined-list') 

Tenga en cuenta que no necesita utilizar serializadores en absoluto al generar las respuestas, también podría extraer todos los campos requeridos en cada instancia, creando datos para la respuesta explícitamente en la vista en sí, pero es una buena forma estándar de Mapa de instancias de modelos en diccionarios de datos.

Con suerte eso te dará suficiente para empezar. 🙂