【问题标题】:How do you return 404 when resource is not found in Django REST Framework在 Django REST Framework 中找不到资源时如何返回 404
【发布时间】:2017-06-21 07:43:35
【问题描述】:

当用户输入错误的 url 时,我的 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),
]

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

【问题讨论】:

  • get_object_or_404

标签: django django-rest-framework http-status-code-404


【解决方案1】:

或者简单地说,你可以使用相同的DRF结构,而不会丢失I18N并保持相同的DRF错误信息:

from rest_framework import viewsets, status, exceptions
from rest_framework.decorators import action
from rest_framework.response import Response

        try:

            codename = get_or_bad_request(self.request.query_params, 'myparam')
            return Response(self.get_serializer(MyModel.objects.get(myparam=codename), many=False).data)
        except MyModel.DoesNotExist as ex:
            exc = exceptions.NotFound()
            data = {'detail': exc.detail}
            return Response(data, exc.status_code)

【讨论】:

  • get_or_bad_request 来自哪里?似乎不在其余文档中。
【解决方案2】:
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)

【讨论】:

    【解决方案3】:

    简单的方法,你可以使用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)
    

    你也可以用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)
    

    为了测试它,一个使用curl命令的例子;

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

    希望对你有帮助..


    更新

    如果您想使用 DRF 处理所有错误 404 url​​,DRF 还提供了APIException,这个答案可能会对您有所帮助; https://stackoverflow.com/a/30628065/6396981

    我会举例说明如何使用它;

    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
    

    确保您的DEBUG = False

    【讨论】:

    • DEBUG=FALSE 试过了,没有得到500 状态@SancaKembang
    • @SancaKembang 我去,用 DEBUG=FALSE 试过了,没有得到 500,django=3.x
    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 2016-08-12
    • 2020-08-26
    • 2019-05-15
    • 1970-01-01
    • 2015-04-27
    相关资源
    最近更新 更多