How to get multiple objects response using rest_framework and Django

I am new to the Django framework and the Django REST framework, but I got the basic setup and implementation. It works like a charm when I call a domain for individual objects, for example. http://mydomain.com/location/1 (where 1 is the primary key). This gives me a JSON response like:

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

.. and http://mydomain.com/country/2 answers like:

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

What I need: Now I need to get several locations, for example. when calling the domain http://mydomain.com/all_locations/ . I would expect an answer like:

 [ {"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} ] 

This is optional:. In the second step, I would like to have several countries and locations in one answer when I call http://mydomain.com/mix_all_locations_countries/ , for example:

 [ {"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"} } ] 

Here's my implementation so far (only showing the location implementation):

in models.py :

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

in serializers.py :

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

in views.py :

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

in urls.py :

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

What I tried: I think I do not need to change the model and serializer, because it works for single objects when calling the domain mentioned above. So I tried to implement LocationsViewSet in views.py and added a new url in urls.py but I failed. Any idea how I could implement it? Maybe just define a method in LocationAPIView and change the url definition similar to this:

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

Thanks in advance, I will appreciate any help.

Regards, Michael

+4
source share
1 answer

First of all, let's just forget about the views at the moment - they make some things simpler, but they also introduce an extra layer of abstraction, which I donโ€™t think you should worry about right now.

The first thing you mentioned as needy is the endpoint of the list, equivalent to your endpoint of the end part. You have received this a long time ago, you just need to provide an additional view next to the existing view.

views.py :

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

Now plug both views into URLconf.

urls.py :

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

Note that I also changed the style of the URL name to make it more standard with the usual Django conventions.

Then you had to view the combined location + countries. You simply cannot use the existing general view for this, since this is a fairly common behavior, but it's easy enough to write a view for ...

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 }) 

And plug the view up.

urls.py :

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

Note that you donโ€™t need to use serializers at all when generating answers, you can also pull out all the necessary fields on each instance, constructing the data for the answer explicitly in the view itself, but this is a nice standard way of matching model instances in data dictionaries.

Hope this gives you enough to get started. :)

+7
source

Source: https://habr.com/ru/post/1499595/


All Articles