如何在Django REST Framework中找不到资源时如何返回404

Kei*_*ase 10 django http-status-code-404 django-rest-framework

当用户输入错误的网址时,我的Django应用会返回HTML错误.如何让DRF返回json格式的错误?

目前我的网址是

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),
]
Run Code Online (Sandbox Code Playgroud)

但如果用户转到127.0.0.1:8000/snip他们得到html格式的错误而不是json格式的错误.

bin*_*npy 22

只需这样做,你可以使用raise Http404,这是你的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)
Run Code Online (Sandbox Code Playgroud)

您也可以使用它Response(status=status.HTTP_404_NOT_FOUND),这个答案是如何处理它:https://stackoverflow.com/a/24420524/6396981

但是之前,在你的内心 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)
Run Code Online (Sandbox Code Playgroud)

要测试它,使用curl命令的示例;

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

# example;

$ curl -X GET http://localhost:8000/snippets/99999/
Run Code Online (Sandbox Code Playgroud)

希望它可以帮助..


更新

如果你想处理所有带有DRF的错误404网址,DRF也会提供相关信息APIException,这个答案可能对你有所帮助; /sf/answers/2143964581/

我将举例说明如何处理它;

1. views.py

from rest_framework.exceptions import NotFound

def error404(request):
    raise NotFound(detail="Error 404, page not found", code=404)
Run Code Online (Sandbox Code Playgroud)

2. urls.py

from django.conf.urls import (
  handler400, handler403, handler404, handler500)

from yourapp.views import error404

handler404 = error404
Run Code Online (Sandbox Code Playgroud)

创造你的 DEBUG = False


小智 9

from rest_framework import status    
from rest_framework.response import Response

# return 404 status code    
return Response({'status': 'details'}, status=status.HTTP_404_NOT_FOUND)
Run Code Online (Sandbox Code Playgroud)


Mas*_*ari 6

一种更简单的方法是使用get_object_or_404django 中的方法:
\nas 在此链接中描述中描述:

\n
\n

get_object_or_404(klass, *args, kwargs)
\n-
在给定模型管理器上调用 get(),但它会引发 Http404 而不是 model\xe2\x80\x99sDoesNotExist 异常。
\n-
klass:从中获取对象的模型类、管理器或查询集实例。

\n
\n

举个例子,注意

\n
obj = get_object_or_404(Snippet, pk=pk)\nreturn obj\n
Run Code Online (Sandbox Code Playgroud)\n

在下面的代码中:

\n
from django.shortcuts import get_object_or_404\nfrom snippets.models import Snippet\nfrom snippets.serializers import SnippetSerializer\nfrom rest_framework.views import APIView\nfrom rest_framework.response import Response\n\nclass SnippetDetail(APIView):\n    """\n    Retrieve, update or delete a snippet instance.\n    """\n    def get_object(self, pk):\n        obj = get_object_or_404(Snippet, pk=pk)\n        return obj\n\n    def get(self, request, pk, format=None):\n        snippet = self.get_object(pk)\n        serializer = SnippetSerializer(snippet)\n        return Response(serializer.data)\n    ...\n
Run Code Online (Sandbox Code Playgroud)\n