Cum se returnează 404 atunci când resursa nu este găsită în Django REST Framework (Programare, Django, Django Rest Framework, Http Status Code 404)

Reimus Klinsman a intrebat.

Când un utilizator introduce o adresă URL care este greșită, aplicația mea Django returnează o eroare HTML. Cum pot face ca DRF să returneze o eroare formatată în format json?

În prezent, uralele mele sunt

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

dar dacă un utilizator merge la 127.0.0.1:8000/snip, primește eroarea formatată html în loc de o eroare formatată json.

Comentarii

  • get_object_or_404 –  > Por Alex78191.
3 răspunsuri
binpy

Modul simplu de a face acest lucru, puteți utiliza raise Http404, aici se află dvs. 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)

De asemenea, puteți să vă descurcați cu Response(status=status.HTTP_404_NOT_FOUND), acest răspuns este modul de a face cu el: https://stackoverflow.com/a/24420524/6396981

Dar, anterior, în interiorul dvs. 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)

Pentru a-l testa, un exemplu care utilizează curl comanda;

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

# example;

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

Sper că vă poate ajuta..


Actualizare

Dacă doriți să vă ocupați pentru toate urile de eroare 404 cu DRF, DRF oferă, de asemenea, despre asta cu APIExceptionacest răspuns vă poate ajuta; https://stackoverflow.com/a/30628065/6396981

Voi da un exemplu cum se face cu ea;

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

Asigurați-vă că DEBUG = False

Comentarii

  • încercat acest lucru cu DEBUG=FALSE Nimic nu am primit un 500 status @SancaKembang –  > Por StackEdd.
  • @SancaKembang și eu ,am încercat asta cu DEBUG=FALSE nimic nu primesc un 500,django=3.x –  > Por xin.chen.
Anil Chauhan
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)

Symon

Sau, pur și simplu, puteți utiliza aceeași structură a DRF, fără a pierde I18N și păstrați același mesaj de eroare 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)