Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework DELETE returns no content in the body

I am using Django Rest Framework and I am making a DELETE request. As opposed to POST, PUT, PATCH, which all return the state of the object post creation/modification, delete does not return anything in the body (just the 204 code).

Having this information would be helpful when trying to tie responses back to their original requests. In particular https://github.com/agraboso/redux-api-middleware does a bad job at telling me what succeeded and what errored)

Is there a way to force DRF to add information about what was deleted in the body of the response?

Thank you!

like image 421
Andrei Cioara Avatar asked Oct 06 '18 20:10

Andrei Cioara


People also ask

What is soft delete in Django REST framework?

Django Soft Delete gives Django models the ability to soft delete(logical delete). it also gives the ability to restore or undelete soft-deleted instances.

What is Raise_exception true?

It is also raised when calling serializer.is_valid with the raise_exception keyword argument: serializer. is_valid(raise_exception=True) The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API.

What is Restapi in Django?

REST APIs are an industry-standard way for web services to send and receive data. They use HTTP request methods to facilitate the request-response cycle and typically transfer data using JSON, and more rarely - HTML, XML and other formats.

What is HyperlinkedModelSerializer?

HyperlinkedModelSerializer is a layer of abstraction over the default serializer that allows to quickly create a serializer for a model in Django. Django REST Framework is a wrapper over default Django Framework, basically used to create APIs of various kinds.

What are routes in Django REST API?

When a client sends request to our Django Rest Api for an endpoint using HTTP request (GET, POST, PUT, DELETE), we need to determine how the server will response by defining the routes. These are our routes: /api/tutorials: GET, POST, DELETE /api/tutorials/:id: GET, PUT, DELETE

Why Django REST framework?

Why Django REST Framework? There are many frameworks for building REST APIs, but we’re gonna use the Django Rest Framework by the following reasons: The Web browsable API is a huge usability win for developers. Authentication policies including packages for OAuth1a and OAuth2. Serialization supports both ORM and non-ORM data sources.

What is the use of request stream in Django?

request.stream returns a stream representing the content of the request body. You won't typically need to directly access the request's content, as you'll normally rely on REST framework's default request parsing behavior. As REST framework's Request extends Django's HttpRequest, all the other standard attributes and methods are also available.

How to setup new Django app for CRUD REST API?

Setup new Django app for CRUD Rest Api Refresh the project directory tree, you can see it now looks like: Now open tutorials/apps.py, you can see TutorialsConfig class (subclass of django.apps.AppConfig ). from django.apps import AppConfig class TutorialsConfig (AppConfig): name = 'tutorials'


2 Answers

Sure thing. In your view, you'll have to override destroy. Default implementation -by the time of writing this answer- is:

def destroy(self, request, *args, **kwargs):
    instance = self.get_object()
    self.perform_destroy(instance)
    return Response(status=status.HTTP_204_NO_CONTENT)
like image 193
Linovia Avatar answered Sep 17 '22 14:09

Linovia


Complementing @Linovia's otherwise complete answer with actionable code.

In the ViewSet, adding the following will help

class WhateverYourModelIsViewSet(viewsets.ModelViewSet):
    def destroy(self, *args, **kwargs):
        serializer = self.get_serializer(self.get_object())
        super().destroy(*args, **kwargs)
        return response.Response(serializer.data, status=status.HTTP_200_OK)

Few things to be aware of:

  • Returning 204 code will actually drop the data, you have to return something else
  • You need to extract the data from the serializer before you call destroy

Edit:

Since I first posted my answer, I found myself in need to do the above quite often. A more scalable solution:

class DestroyWithPayloadMixin(object):
     def destroy(self, *args, **kwargs):
         serializer = self.get_serializer(self.get_object())
         super().destroy(*args, **kwargs)
         return response.Response(serializer.data, status=status.HTTP_200_OK)

class WhateverYourModelIsViewSet(DestroyWithPayloadMixin, viewsets.ModelViewSet):
   # Your implementation 
   pass
like image 24
Andrei Cioara Avatar answered Sep 16 '22 14:09

Andrei Cioara