Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raising Exceptions in Django REST

Tags:

django

I'm trying to test the exceptions within the django rest framework. Based on http://www.django-rest-framework.org/api-guide/exceptions/ raising NotFound,

By default this exception results in a response with the HTTP status code "404 Not Found".

However when I issue a GET (to /example1) I get a 500 with ,

Request Method: GET
Request URL:    http://192.168.59.103:8002/example1
Django Version: 1.8.3
Exception Type: NotFound
Exception Value:    
not found
Exception Location: /home/djangoapp/testtools/api/views.py in example1, line 7
Python Executable:  /usr/bin/python

details below,

settings.py

REST_FRAMEWORK = {'EXCEPTION_HANDLER':'rest_framework.views.exception_handler'}

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
)

urls.py

from django.conf.urls import include, url
from api import views

urlpatterns = [
    url(r'example1', views.example1),
]

views.py

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.exceptions import APIException,ParseError,NotFound

def example1(request):                                                                                                                               
    raise NotFound("not found")

Any ideas ?

like image 481
felix001 Avatar asked Aug 01 '15 20:08

felix001


People also ask

How do I create a custom exception in Django REST framework?

Custom exception handlingThe exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.

Can we use Django for REST API?

Django REST framework (DRF) is a powerful and flexible toolkit for building Web APIs. Its main benefit is that it makes serialization much easier. Django REST framework is based on Django's class-based views, so it's an excellent option if you're familiar with Django.


2 Answers

from rest_framework.exceptions import NotFound

The class NotFound is extended from APIException. The default status code for APIException is 500 Internal Server Error, whereas for NotFound is 404.

So according to me here you are trying to throw a rest framework exception in a pure django view. I wrote a test case here to check what are the odds of getting the error raised. Guess what a simple django view trying to raise a rest framework exception is not recognized as an error to the view. But on providing the decorator and declaring it an API View it enters the exception_handler

So when you do:

from rest_framework.decorators import api_view

@api_view()
def example1(request):
    raise NotFound('not found')

This is now recognized as an exception thrown by the API which enters the default rest_framework EXCEPTION_HANDLER provided by you, where it returns the response for any given exception.

Its docstring says:

Returns the response that should be used for any given exception. By default we handle the REST framework APIException, and also Django's built-in ValidationError, Http404 and PermissionDenied exceptions. Any unhandled exceptions may return None, which will cause a 500 error to be raised.

like image 79
Arpit Goyal Avatar answered Oct 18 '22 23:10

Arpit Goyal


I'm not sure why you are doing this. That's an internal exception used by DRF when it can't find a resource. But you're using it in a standard Django view, outside any of the DRF machinery. If you want to do that, you should use the standard Django exception:

from django.core.exceptions import Http404

def example1(request):
    raise Http404('not found')
like image 44
Daniel Roseman Avatar answered Oct 18 '22 21:10

Daniel Roseman