코깽이의 코딩일기

Django - 첫 번째 장고 앱 작성하기, part 3 본문

Django/Django - 튜토리얼

Django - 첫 번째 장고 앱 작성하기, part 3

코깽이 2023. 8. 13. 18:58
반응형

 


공식문서

https://docs.djangoproject.com/ko/4.2/intro/tutorial03/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com


1. 개요

 

Django에서는 URLconfs라는 것을 이용해서 패턴을 만들고 view에 연결한다고 나와있습니다. polls 앱에서 4가지 view를 만드는 과정을 해보겠습니다.


2. 뷰 추가하기

먼저 polls앱 views.py에 3개의 함수를 작성합니다.

각 함수는 세부사항, 결과, 현재 투표에 관한 내용을 return 합니다.

 

이어서 urls.py에 해당 함수들을 추가해 줍니다. 

먼저 path에는 url이 오고 이어서 polls/views.py에 작성한 함수의 이름 그리고 이 패턴에 대한 이름을 정해줍니다.

마지막에 작성한 name부분은 필수는 아닙니다. 하지만 URL 역참조를 통해서 URL을 하드코딩하지 않고 유지보수가 용이하고 중복되지 않는 URL패턴을 만들기 위해서 사용해 주는 것이 좋습니다.


3. 뷰가 실제로 뭔가를 하도록 만들기

View는 db 읽기, 템플릿 사용, 파일 생성 등등 python의 어떤 라이브러리라도 사용이 가능하고 필요한 것은 객체 or 예외이다 라는 내용입니다.

views.py에서 index라는 함수를 만들어 질문 선택지를 발행일에 따라 불러오려면 아래와 같은 코드를 하드코딩했어야 했습니다.

하지만 이제 templates를 이용해서 index.html이라는 파일을 만들고 활용해 보겠습니다.

 

우선 polls안에 templates라는 이름으로 폴더를 만들어줍니다.

바로 templates 안에 파일을 만들어서 진행하는 것이 아니라고 나와있습니다.

설치된 앱 - templates를 검색한다고 적혀있으니 우리는 polls/templates/polls/index.html 이런 식으로 파일 경로를 구성해주어야 합니다.

 

파일 경로를 한번 더 확인해 주고 html파일을 생성하겠습니다.

 

튜토리얼은 불안전한 HTML 예제이다라고 하니 우리는 이 부분은 보안을 하고 진행해 보겠습니다.

왼쪽 파일 탐색기를 보시면 templates|polls|index.html이 만들어진 걸 볼 수 있습니다.

저는 경로 부분을 확실히 보여드리기 위해서 터미널에서 마지막 경로인 polls까지 이동을 하고 명령어로 생성을 하였고

dir 명령어를 이용해 파일이 있는 것을 확인했습니다.

 

! + tab을 눌러서 기본 골격 만들어주고 title은 필요 없으니 지우고 body안에 해당 내용을 작성해 줍니다.

 

views.py에 작성된 index도 사진과 같이 수정해 줍니다.

해당 코드는 polls/index.html파일을 loader을 이용해 불러오고 context에 전달합니다.

 

하지만 Django에서는 쉽게 표현할 수 있는 단축 기능을 제공한다고 합니다.

더 편한 기능이 있는데 한번 써보도록 합시다.

새롭게 render를 선언해 주는 거 잊지 마시고 코드를 수정해 줍니다. 저는 이전에 내용들을 정리하기 위해서 주석 처리하면서 진행한 거라 주석은 무시하셔도 됩니다.

render의 인자는 request 객체, 템플릿 이름, context 사전형 객체입니다.

 

실행을 시켜보니 html을 처음 사용해 보시는 분이라면 이게 제대로 작동하는 건지 아닌지 잘 모를 수 있으니

예제에서 간단하게 제목이랑 Polls List!!! 를 확인 가능하게 수정해 주고 실행시키겠습니다.

127.0.0.1:8000/polls로 들어오니 질문지 목록 확인이 가능합니다.

코드는 5개까지 뽑아서 출력하는 코드이지만 우리가 만든 질문지가 1개밖에 없어서 What's up만 보입니다.

 

index.html 코드 안에 What's up을 누르면 해당 페이지로 이동되는 링크를 걸어놓았는데 이것도 확인해 보겠습니다.

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

127.0.0.1:8000/polls/1/ 로 이동하면서 질문의 id에 해당하는 페이지로 잘 넘어와집니다.


4. 404 에러 일으키기

 

http 404 에러를 발생시키는 실습을 해보겠습니다.

 

예외 처리를 통하여 id가 존재하지 않는 경우 404 에러를 발생시키고 존재하는 경우에는 polls/detail.html을 불러오면서 question 객체를 넘겨줍니다.

detail.html에는 간단하게 전달받은 객체에 대한 값을 출력해 보도록 하겠습니다.

 

이후에 실행을 시켜서 존재하지 않는 question id를 url에 입력해 접속을 하겠습니다.

Page not found 404 에러가 발생하면서 Question des not exist라는 메시지가 보입니다.

Question id에 1을 넣어서 url을 입력했을 경우 결과를 확인해 보겠습니다.

해당 질문의 내용의 detail.html이 잘 출력이 됩니다.

 

http 404 에러를 발생시키는 방법이 Django에서 단축 기능으로도 제공합니다.

get_object_or_404() 함수로 사용가능합니다.

get_object_or_404() 함수는 django.shortcuts안에 들어있습니다.

from django.shortcuts import render, get_object_or_404

이렇게 import에 추가해 주고 코드를 돌려서 결과를 확인해 보겠습니다.

Http404() 함수를 사용했을 때와 동일하게 404 에러가 발생합니다.

No Question matches the given query라는 메시지도 확인할 수 있습니다.

비슷한 기능을 가진 함수로는 get_list_or_404() 함수가 있습니다. get_obejct_or_404() 함수와 동일하게 이름에 나와잇는 get() 함수가 아닌 filter() 함수를 이용해서 list가 비어있는 경우 http404 예외를 발생시킵니다.

 


get_object_or_404()와 Http404()를 사용하는 이유가 뭘까?

1. 개발자가 예외처리를 명시하지 않아도 되니 간편하다.

2. 함수의 이름에서 보이는 것과 같이 코드의 의도를 명확하게 알 수 있어서 가독성이 좋다.

3. 객체를 불러올 때마다 예외처리 코드를 작성할 필요가 없어 반복되는 코드를 줄일 수 있다.

4. 404 예외처리는 HTTP예외이고 ObjectDoesNotExist는 Django의 ORM에서 사용되는 예외이다. 즉 404는 웹 요청에 대한 응답으로 발생하는 예외, ObjectDoesNotExist는 DB나 ORM 관련 작업에서 객체가 존재하지 않을 경우 발생하는 예외로 오륲처리를 더 효율적으로 관리할 수 있다.


5. 템플릿 시스템 사용하기

context 변수 question이 있을 때 detai.html을 수정하고 어떻게 보이는지 확인해 봅시다.

템플릿 시스템의 변수의 속성에 접근하기 위해서 점-탐색(dot-lookup) 문법을 이용한다고 합니다.

<h1>{{ question.question_text }}</h1>

해당 코드에서 Django는 question 객체를 사전형으로 탐색합니다. 실패 시 속성값 - 리스트 인덱스 탐색 순서로 진행됩니다.

지금은 Django만의 템플릿 언어가 있다.라는 정도만 알고 넘어가겠습니다.

 

추가적인 내용은 공식문서를 읽어보시면 좋을 것 같습니다.

https://docs.djangoproject.com/ko/4.2/topics/templates/

 

Django

The web framework for perfectionists with deadlines.

docs.djangoproject.com


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

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

index.html의 해당 url작성은 하드코딩으로 이루어져 있습니다. 만약 프로젝트가 점점 커져나갈수록 URL을 변경하는 게 어려워집니다. 이러한 하드코딩으로 인해 발생하는 경로에 대한 의존성을 urls 모듈의 path() 함수에서 이름을 정의하고

{% url %} template 태그를 이용해서 제거할 수 있습니다.

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

태그를 사용해서 코드를 수정해 줍니다.

url에 문제없이 접속하였습니다.


7. URL의 이름 공간 정하기

 

지금 튜토리얼에서는 polls라는 앱 하나만 가지고 진행 중입니다. 우리가 urls.py에서 각 path()들의 name을 정해주기도했고요. 만약 polls가 아닌 다른 앱이 존재하고 path()들의 name들 중에 겹치는 게 발생할 수도 있습니다. polls앱에도 name이 detail인 path()와 다른 앱에서도 name이 detail인 path()가 존재하는 경우를 생각해 보면 우리가 작성한 코드

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

{% url 'name' %} 형식으로 작성된 코드들은 어떤 detail에 연결될지 문제가 생길 수 있습니다. 이러한 경우 앱의 이름공간(namespace)을 설정해서 해결할 수 있습니다.

 

이해도를 높이기 위해서 앱 이름과 namespace의 이름을 동일하게 작성하였습니다.

app_name = "polls"

이후 아까 우리가 {% url %} template 태그를 이용한 부분을 수정하겠습니다.

 

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

기존 name을 작성하는 부분 앞에 "app_name:detail" 구조로 코드를 수정해 주시면 이제 다른 앱이 생기고 똑같이 detail이란 값을 주더라도 해당 코드는 polls앱의 detail을 찾아갈 것입니다.


 

 

반응형