web-dev-qa-db-fra.com

Comment renvoyer 404 lorsque la ressource est introuvable dans Django REST Framework

Lorsqu'un utilisateur saisit une URL incorrecte, mon application Django renvoie une erreur HTML. Comment puis-je demander à DRF de renvoyer une erreur au format json?

Actuellement, mes URL sont

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),
]

mais si un utilisateur passe à 127.0.0.1:8000/snip, il obtient l'erreur au format html plutôt qu'une erreur au format json.

10
Kei Nagase

Pour le faire simplement, vous pouvez utiliser raise Http404, Voici votre 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)

Vous pouvez également le gérer avec Response(status=status.HTTP_404_NOT_FOUND), cette réponse est de savoir comment faire avec lui: https://stackoverflow.com/a/24420524/6396981

Mais auparavant, dans votre 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)

Pour le tester, un exemple utilisant la commande curl;

$ curl -X GET http://localhost:8000/snippets/<pk>/

# example;

$ curl -X GET http://localhost:8000/snippets/99999/

J'espère que cela peut aider ..


Mise à jour

Si vous souhaitez gérer toutes les URL d'erreur 404 avec DRF, DRF fournit également à ce sujet avec APIException , cette réponse peut vous aider; https://stackoverflow.com/a/30628065/6396981

Je vais vous donner un exemple comment en faire;

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

Assurez-vous que votre DEBUG = False

20
Sanca Kembang