Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you return 404 when resource is not found in Django REST Framework

When a user inputs a url that is wrong, my Django app returns an HTML error. How can I get DRF to return a json formatted error?

Currently my urls is

from django.conf.urls import url from snippets import views  urlpatterns = [     url(r'^snippets/$', views.snippet_list),     url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail), ] 

but if a user goes to 127.0.0.1:8000/snip They get the html formatted error rather than a json formatted error.

like image 429
Reimus Klinsman Avatar asked Feb 03 '17 20:02

Reimus Klinsman


People also ask

How does Django error 404 return?

The Http404 exception In order to show customized HTML when Django returns a 404, you can create an HTML template named 404. html and place it in the top level of your template tree. This template will then be served when DEBUG is set to False .

How do I show 404 in Django?

You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page. Let's do that by turning off Django debug mode. For this, we need to update the settings.py file.

How do I return a response in Django REST framework?

core. servers. basehttp import FileWrapper ... if format == 'raw': zip_file = open('C:\temp\core\files\CDX_COMPOSITES_20140626. zip', 'rb') response = HttpResponse(FileWrapper(zip_file), content_type='application/zip') response['Content-Disposition'] = 'attachment; filename="%s"' % 'CDX_COMPOSITES_20140626.

What is the correct command to run Django REST server?

Let's make sure the app is up and running by using the Django runserver command. (drf) $ python3 manage.py runserver Django version 3.1. 5, using settings 'my_awesome_django_project. settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.


1 Answers

Simply way to do it, you can use raise Http404, here is your views.py

from django.http import Http404  from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView  from yourapp.models import Snippet from yourapp.serializer import SnippetSerializer   class SnippetDetailView(APIView):      def get_object(self, pk):         try:             return Snippet.objects.get(pk=pk)         except Snippet.DoesNotExist:             raise Http404      def get(self, request, pk, format=None):         snippet = self.get_object(pk)         serializer = SnippetSerializer(snippet)         return Response(serializer.data, status=status.HTTP_200_OK) 

You also can handle it with Response(status=status.HTTP_404_NOT_FOUND), this answer is how to do with it: https://stackoverflow.com/a/24420524/6396981

But previously, inside your serializer.py

from rest_framework import serializers  from yourapp.models import Snippet   class SnippetSerializer(serializers.ModelSerializer):     user = serializers.CharField(         source='user.pk',         read_only=True     )     photo = serializers.ImageField(         max_length=None,         use_url=True     )     ....      class Meta:         model = Snippet         fields = ('user', 'title', 'photo', 'description')      def create(self, validated_data):         return Snippet.objects.create(**validated_data) 

To test it, an example using curl command;

$ curl -X GET http://localhost:8000/snippets/<pk>/  # example;  $ curl -X GET http://localhost:8000/snippets/99999/ 

Hope it can help..


Update

If you want to handle for all error 404 urls with DRF, DRF also provide about it with APIException, this answer may help you; https://stackoverflow.com/a/30628065/6396981

I'll give an example how do with it;

1. views.py

from rest_framework.exceptions import NotFound  def error404(request):     raise NotFound(detail="Error 404, page not found", code=404) 

2. urls.py

from django.conf.urls import (   handler400, handler403, handler404, handler500)  from yourapp.views import error404  handler404 = error404 

Makesure your DEBUG = False

like image 105
binpy Avatar answered Oct 03 '22 08:10

binpy