The get_object_or_404 shortcut function in Django when encountering an exception gives a very nice error message in the following format:
'No %s matches the given query.' % queryset.model._meta.object_name)
However, while using this inside a DRF 3.X Class based view, the final 404 response data has a very stripped down version, which is as follows:
{"detail": "Not found."}
As is evident, the DRF message is very generic with no information about the Model name.I am assuming that the DRF NotFound Exception class defined here strips down the message to its current bare minimum.
How can I get the original nice error message that Django returns in-spite of using it within a DRF Class Based View ?
How to use get_object_or_404() in a Django Project? This function calls the given model and get object from that if that object or model doesn't exist it raise 404 error.
Django views facilitate processing the HTTP requests and providing HTTP responses. On receiving an HTTP request, Django creates an HttpRequest instance, and it is passed as the first argument to the view function. This instance contains HTTP verbs such as GET, POST, PUT, PATCH, or DELETE.
APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.
The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects. The default behavior of REST framework's generic list views is to return the entire queryset for a model manager.
The default exception handler for an APIView
class is decided by the get_exception_handler
method. Ie,
def get_exception_handler(self):
"""
Returns the exception handler that this view uses.
"""
return self.settings.EXCEPTION_HANDLER
In other words the handler function that an APIView
class use by default is rest_framework.views.exception_handler
(Which is specified on the default settings
).
As per the DRF Doc,
By default DRF handle the REST framework
APIException
, and alsoDjango's built-inHttp404
andPermissionDenied
exceptions.
Since in this case you want to customize the error message only for the Http404
, you can create your own handler like this.
ie,
from rest_framework.views import exception_handler
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, context)
# Now overide the error message.
if response is not None and isinstance(exc, Http404):
# set the custom message data on response object
response.data['detail'] = exc.args[0] # exc.args[0] will have the message text,
return response
Then place this custom handler in your project settings.
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
Note: This solution is not tested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With