How to change viewset retrieve response in Django Rest Framework?
If you want to modified retrieve
functionality of ModelViewset you can overwrite its retrieve
method and do what ever you want. mixin's
link
class AirportList(viewsets.ModelViewSet):
queryset = models.Airport.objects.all()
serializer_class = AirportSerializer
def retrieve(self, request, *args, **kwargs):
# do your customization here
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
How to explore DRF
I think best way to look after any new thing is their codebase. For ModelViewset you should start from views
link and explore what are the functionality it provide and how i can customize them.
murthaA
Updated on June 04, 2022Comments
-
murthaA almost 2 years
I'm currently developing a Web App that uses an API as the backend for a University Project.
And I've read that DRF is the fastest and easiest way to develop and deploy an API, I already followed through their entire official
documentation and I don't seem to understand how I could the following in their ViewSet and Serializer.
Here's one endpoint of my API called airports.
All airports available in the USA
Returns json/csv list of links to the available airports in the USA.
URL
/airports
Method:
GET
Success Response:
- Code: 200
Content:
[ { "airport": { "code": "PHL", "name": "Philadelphia, PA: Philadelphia International", "id": 123, "url": "/airports/123" }, { "airport": { "code": "AHR", "name": "American Hour Rapid", "id": 125, "url": "/airports/125" } . . . ]
- Code: 200
Show Airport Informations
Returns all links to the carriers operating at a specific airport, a link to the related statistics on a specific month and year and also a link to the airport routes. If in case neither the year or the month are specified, the default will be the one with the most recent date.
- URL
/airports/:id
- Method:
GET
URL Params
Required:
id=[integer]
Success Response:
{ "airport": { "code": "PHL", "name": "Philadelphia, PA: Philadelphia International", "id": 123, "url": "/airports/123" }, "routes_link": "/airports/123/routes", "carriers": [ { "id": 124, "url": "/carriers/124?airport_id=123", "statistics_url":"/airports/1carrier=124&statistics='flights'" }, . . . ] }
I was able to do /airports properly listing all of the available airports in the database but when using the ViewSet I don't know how to "customize" the response when trying to retrieve information about only one airport specified by the id and in the application the routes are going to be generated dynamically and I was planning to add to the response body and not another field in the model.
Models:
class Carrier(models.Model): code = models.CharField(max_length=10) name = models.TextField() #airports = models.ManyToManyField(Airport) def __str__(self): return self.name class Airport(models.Model): code = models.CharField(max_length=10) name = models.TextField() carriers = models.ManyToManyField(Carrier, related_name='airports') def __str__(self): return self.name
Serializers:
class AirportSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Airport fields = ('id', 'name', 'code', 'url') class CarrierSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Carrier fields = ('id', 'name', 'code', 'url')
View:
class AirportList(viewsets.ModelViewSet): queryset = models.Airport.objects.all() serializer_class = AirportSerializer # @Override something here?
Anyone has a tip on how I could approach this using DRF or any kind of learning material I could use?
-
Mr.L about 4 yearsOverriding retrieve is not working for me, even after modifying it I am getting the same response, even though I am returning "Hello".
-
Alfarhan Zahedi about 4 years@Mr.L Maybe you are overriding the wrong method. You need to override
retrieve()
if you are just returning a single instance of the model under consideration. If you are returning a list of instances, try overriding thelist()
method. You can find its definition in the mixin's link shared in the above answer.