터칭 데이터

장고(Django) 404 에러 처리하기 본문

장고 (Django)

장고(Django) 404 에러 처리하기

터칭 데이터 2023. 11. 3. 16:18

404에러는 사용자가 웹 사이트에 존재하지 않는 URL을 요청하면 띄우는 에러입니다.

 

 

 

존재하는 question id 3번 대신 1000번을 입력하면

 

 

 

 

 

 

에러가 뜨는데

 

 

polls 앱의 views.py 파일의 위와 같이 음영처리된 코드를 실행하다 에러가 발생했다고 합니다.

 

 

>>> question = Question.objects.get(pk=1000)
Traceback (most recent call last):
  # (생락...)
polls.models.Question.DoesNotExist: Question matching query does not exist.

 

쉘에서 코드를 똑같이 입력해보면 입력된 1000으로 Question의 id를 찾지 못했다는 뜻인데요.

 

 

개발자 도구 Network에서도 자세히 살펴보면

 

분명 사용자가 잘못된 URL을 입력해 발생한 에러임에도 404에러가 아닌 500에러가 발생합니다.

(500에러는 사용자가 아닌 서버의 문제라는 뜻으로 이해하시면 쉽습니다.)

 

 

서버내에서 없는 ID를 찾다가 발생한 에러이므로 500 에러가 맞지 않나 싶기도 하지만 사용자의 URL입력이 잘못된 것이 더 근본적인 원인이기 때문에 404에러를 띄워주는 것이 더 정확합니다.

 

그러면 404 에러를 어떻게 띄워줘야 할까요?

 

 

 

 

 

 

 

 

직접 코드를 작성해 404 에러 띄우기

 

우리가 문제가 발생했던 파일 polls/views.py로 가보겠습니다.

 

 

detail 메서드를 수정했습니다.

 

전과 같이 코드를 실행하되 Question 모델에서 DoesNotExist가 발생하면 "Question does not exist"를 띄우라는 코드입니다. Http404를 사용하기 위해 django.http에서 Http404 라이브러리를 import 했습니다.

 

위의 웹페이지 에러 화면에서 DoesNotExist가 발생했기 때문 except에 DoesNotExist를 띄웠습니다.

 

 

 

뷰를 수정했으니 브라우저에서 새로고침을 해볼까요

 

 

맨 첫줄에 Page not found (404) 에러를 띄우고

두번째 줄에 우리가 띄울 문자열로 입력했던 "Question does not exist"가 의도한대로 출력됩니다.

 

 

 

 

 

 

장고의 숏컷으로 404에러를 더 간단하게 구현하기

 

우리가 위에서 views.py에 작성한대로

모델 클래스를 이용해 값을 가져올 때, 그 값이 존재하지 않으면 404를 raise하는 부분은 매우 자주 사용되는 기능입니다.

 

그래서 장고에서는 이를 간단하게 구현할 수 있는 숏컷(shortcuts)을 제공합니다.

 

 

다시 polls/view.py 뷰로 돌아가

 

shortcuts에서 get_object_or_404를 임포트합니다.

벌써 이름부터 객체를 가져오거나 그렇지 못하면 404에러를 띄운다는 느낌이 옵니다.

 

이를 detail 메서드에서 아까 작성한 try~ except 대신에 사용합니다.

get_object_or_404는 인자로 사용할 모델의 클래스를 첫번째로, 그 모델 객체의 어떤 값을 가져올지를 두번째로 받습니다.

여기서는 기본키인 pk(question.id)가 question_id와 같은 것을 찾는다는 명령을 두번째 인자로 받았습니다.

 

이제 get_object_or_404는 유효한 객체를 찾았다면 정상출력하고 그렇지 못하다면 404에러를 띄웁니다.

 

(위의 이미지에서는 지우지 못했지만 Http404를 import하는 4번줄 코드도 더 이상 사용하지 않으니 지워주세요!)

 

 

브라우저에서 새로고침을 진행하면

 

 

존재하지 않는 ID 1000으로 question을 찾으니

 

 

 

 

404 에러가 정상적으로 뜹니다.

 

 

 

try except 대신 장고 숏컷에서 제공하는 get_object_or_404를 이용하면 더 간단하고 깔끔하게 404에러를 처리할 수 있습니다.