Hande Error Http404 in view

Hi have this view:

# Last Audit By Line
class LastAuditByLine(APIView):
    def get_object(self, id):
        try:
            return Line.objects.get(id=id)
        except Line.DoesNotExist:
            raise Http404

    @swagger_auto_schema(
        operation_summary="Get Last Audit By Line",
        operation_description="Get Last Audit By Line",
        responses={
            status.HTTP_200_OK: response_200(AuditSerializer(many=True)),
            status.HTTP_404_NOT_FOUND: response_404(),
        },
    )
    def get(self, request, id, format=None):
        if self.get_object(id):
            audit = Audit.objects.filter(line=id).order_by("-audit_date")[:1]
            serializer = AuditSerializer(audit, many=True)
            return JsonResponse(serializer.data, safe=False)

On the funcion get_object I want to handle the error and add some custom message like “That Line Does Not Exists”.
If I add a print instead of Http404 I have this error:

AssertionError at /fjbe_prod_panel/api/audit/2
Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'NoneType'>

Hey there!

And what if instead of doing:

You did:

raise Http404("That Line Does Not Exists”)

Just a clean code tip here:

You don’t need this if statement here:

Your get_object function will always return an object, or will raise a exception (and if is raised, then the function won’t return to the caller, and that’s your get function).
So you can:

def get(self, request, id, format=None):
    line = self.get_object(id)
    audits = Audit.objects.filter(line=line).order_by("-audit_date")[:1]
    # or even use the forward relation manager, if you didn't set the `related_name` on the line field of the Audit model
   #  line.audit_set.order_by("-audit_date")[:1]
    ...
1 Like

Hi @leandrodesouzadev thanks for your help.
I have done some tests and I get the result I was waiting for.
Create this function:

# Function to handle error message
def error_response(message, status, error=None):
    response = dict()
    response["message"] = message

    return JsonResponse(response, status=status)

and inside the view I made some changes

def get_object(self, id):
        try:
            Line.objects.get(id=id)
        except Line.DoesNotExist:
            return 1

    @swagger_auto_schema(
        operation_summary="Get Last Audit By Line",
        operation_description="Get Last Audit By Line",
        responses={
            status.HTTP_200_OK: response_200(AuditSerializer(many=True)),
            status.HTTP_404_NOT_FOUND: response_404(),
        },
    )
    def get(self, request, id, format=None):
        if self.get_object(id) == 1:
            message = "This Line Does Not Exist"
            return error_response(
                message=message,
                status=status.HTTP_404_NOT_FOUND,
            )
        else:
            audit = Audit.objects.filter(line=id).order_by("-audit_date")[:1]
            serializer = AuditSerializer(audit, many=True)
            return JsonResponse(serializer.data, safe=False)

This solutions works perfectly