티스토리 뷰

반응형

이전 포스팅에서 localhost:8000/polls/ 로 접속하면 index.html 이라는 템플릿을 보여줬습니다.

 

 

index.html은 이렇게 구현되어있습니다.

 

 

그래서 저 목록 아이템을 누르면 polls > urls.py 에 있는 urlpatterns 중, "/polls/question.id/" 에 매칭되는 detail함수를 불러주고

 

 

polls > views.py에 있는 detail 함수는 이렇게 생겼기 때문에

 

이런 화면을 보여주게 되는거죠 

 

 

index함수를 템플릿을 만들어서 연결시켜줬던 것 처럼 detail함수도 작업을 시작하겠습니다.

polls/templates/polls 디렉토리에 가서 detail.html 파일을 만들어주세요. 

 

 

템플릿 문서에 보면 {{ }} 는  변수를 의미하고 context로 부터 온 value값을 나타낸다 라고 나와있습니다. 

사진에 있는 예시를 참고해주세요

 

 

 

 

그 다음, detail 함수는 이런 모습이여야하겠죠?! 

 

그러면 Question 객체를 가져오는 코드를 작성해봅시다. 

 

특정 객체를 가져오는 코드는 이런식으로 할 수 있는데요, 

 

https://docs.djangoproject.com/en/3.0/topics/db/queries/

 

pk (= primary key) 를 기준으로 객체를 가져와봅시다. 

 

 

그리고 아래에 접속해보면 Question이 잘 나오는 것을 볼 수 있습니다. 

 

 

만약 존재하지 않은 primary key로 요청을 하면 어떻게 될까요?!

현재 Question DB에는 두개의 객체만 있는데 3을 줘보겠습니다. 

 

이런 에러 화면이 뜹니다. 

 

 

이런 응답말고 사용자에게 우리가 주고 싶은 응답을 줘봅시다. 

 

404 에러 일으키기

 

우선 django.http 모듈의 Http404를 import 해주고 

 

from django.http import Http404

 

특정 question을 가져오다가 예외가 생기면(ex. 위의 상황처럼 존재하지않는 pk로 요청)

Http404 exception을 일으키도록 코드를 바꿔주세요. 

 

 

Http404 exception을 쓰면 장고는 일반적으로 쓰이는 HTTP error 404 코드랑 Page not Found 라는 화면을 준다고 합니다. 

 

 

 

그리고 다시 존재하지않은 primary key로 요청하면

이제 Page not found 화면과 "Question does not exist" 라는 화면이 나오게 되네요

근데 디버깅 모드가 켜져있어서 저렇게 디테일한 정보까지 나오는 것이고 

 

 

mysite > settings.py 에 가셔서 디버깅 모드를 끄고 접속해보면 

 

 

 

이렇게 standard 404 page가 잘 나오는 것을 볼 수 있네요

 

get_object_or_404()

 

객체가 존재하지 않을때 예외를 발생시키는것은 자주 쓰이는 용법이라서 Django에서는 이 기능에 대한 단축 기능을 제공한다고 합니다 ( 👍👍)  

 

django.shortcuts 모듈에서 render뿐만 아니라 get_object_or_404 도 import 해주세요

from django.shortcuts import render, get_object_or_404

 

그리고 detail함수를 아래와 같이 바꿔주세요 

 

 

 

그리고 이와 비슷한  get_list_or_404() 함수도 있다고 합니다. 리스트가 비어있을 경우, Http404 예외를 발생시켜주는 함수입니다.

 

 

 

템플릿에서 하드코딩된 URL 제거하기

 

polls > templates > polls 의 index.html에 가보면 
이렇게 url이 하드코딩 되어있는 것을 볼 수 있습니다.

이러한 강력하게 결합되고 하드코딩된 접근방식의 문제는 수많은 템플릿을 가진 프로젝트들의 URL을 바꾸는 게 어려운 일이 된다는 점입니다.  

 

 

하지만 우리는 polls > urls.py에서 urlpattersn를 정의 할때 name을 다 설정해줬습니다. 

 

 

템플릿의 {% url %} 태그를 사용하여  하드 코딩된 URL을 제거할 수 있고 이로인해 URL 경로들의 의존성을 제거할 수 있습니다...!!

 

 

이렇게 바꿔주면

예를 들어 polls/12/ 에서 polls/specifics/12/로 URL를 바꾸고 싶을 때, 

 

polls > urls.py 에 이렇게 되어있는 코드를 

이렇게만 바꿔주면 된다는 거죠..!! 즉 오직 한군데에서만 바꿔주면 됩니다...!! 

 {% url %} 태그 를 사용안했다면 저 URL를 참조하고 있는 모든 <a href= ""></a> 태그를 찾아서 일일이 다 바꿔줘야하는 노동을 하게 될 뻔 했습니다. 😱

 

URL의 이름공간 정하기

튜토리얼의 프로젝트 mysite는 polls라는 앱 하나만 가지고 진행했습니다.

하지만 실제 Django 프로젝트는 앱이 몇개라도 올 수 있습니다.

예를 들어, 동일한 프로젝트에 polls앱과 blog앱이 있는데, 둘다 detail이라는 뷰를 가지고 있다고 가정해봅시다.

 

장고는 아래의  {% url %} 템플릿태그를 보고 어떤 앱의 뷰에서 URL을 생성하는 건지 알 수 있을까요....?

{% url 'detail' question.id %}

 

이를 위해 URLconf에 이름공간(namespace)을 추가합니다. 

polls > urls.py 파일에 app_name을 추가하여 앱의 이름공간(namespace)을 설정할 수 있습니다.

 

(이름공간? namespace? 라는 네이밍이 너무 잘 와닿지 않네요ㅠㅠ 😱)

 

아무튼 polls > urls.py 에 가서  app_name을 추가해주세요 

 

 

그 다음, polls > templates > polls > index.html  에 가서

 

이렇게 되어있던 것을

{% url 'detail' question.id %}

 

이렇게 바꿔주세요 

{% url 'polls:detail' question.id %}

 

 

그럼 이제 장고는 여러개의 앱에 detail뷰가 있더라도 appName을 보고  "polls 앱의 detail 이군" 이라고 알 수 있게 되는 것입니다..!! 

반응형
댓글