[Fixed]-Return Custom 404 Error when resource not found in Django Rest Framework

22πŸ‘

βœ…

You are looking for handler404.

Here is my suggestion:

  1. Create a view that should be called if none of the URL patterns match.
  2. Add handler404 = path.to.your.view to your root URLconf.

Here is how it’s done:

  1. project.views

    from django.http import JsonResponse
    
    
    def custom404(request, exception=None):
        return JsonResponse({
            'status_code': 404,
            'error': 'The resource was not found'
        })
    
  2. project.urls

    from project.views import custom404
    
    
    handler404 = custom404
    

Read error handling for more details.

Django REST framework exceptions may be useful as well.

πŸ‘€Ernest

6πŸ‘

according to django documentation :
Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL. ref: https://docs.djangoproject.com/en/1.8/topics/http/urls/

so you can just add another url in urlpatterns after the one you created and it should match all url patterns and send them to a view that return the 404 code.

i.e :

urlpatterns = [
url(r'^mailer/$', views.Mailer.as_view(), name='send-email-to-admin'),
url(r'^.*/$',views.Error404.as_view(),name='error404')]
πŸ‘€sabtikw

0πŸ‘

@Ernest Ten’s answer is correct. However, I would like to add some input if you’re using an application that handles both browser page loading and API as call.

I customized the custom404 function to this

def custom404(request, exception=None):
    requested_html = re.search(r'^text/html', request.META.get('HTTP_ACCEPT')) # this means requesting from browser to load html
    api = re.search(r'^/api', request.get_full_path()) # usually, API URLs tend to start with `/api`. Thus this extra check. You can remove this if you want.

    if requested_html and not api:
        return handler404(request, exception) # this will handle error in the default manner

    return JsonResponse({
        'detail': _('Requested API URL not found')
    }, status=404, safe=False)
πŸ‘€Koushik Das

0πŸ‘

update of Ernest Ten answer:

You should also include
in urls.py

from django.http import JsonResponse
...other urls...
handler404 = lambda request, exception=None: JsonResponse({'error': '404: The resource was not found'}, status=404)  
πŸ‘€suhailvs

Leave a comment