Web/Django

Django(장고) 템플릿과 데이터 조회 및 URL 매핑하기

daeunnniii 2021. 8. 2. 03:11
728x90
반응형

1. 데이터 목록

notes/views.py 파일의 index 함수를 다음과 같이 작성한다.

from django.shortcuts import render
from .models import Question

def index(request):
    question_list = Question.objects.order_by('-create_date')   #create_date를 역순으로 정렬
    context = {'question_list': question_list}
    return render(request, 'notes/question_list.html', context)

Question은 이전 게시물에서 생성한 모델 이름이고, Question.objects.order_by(기준)로 데이터를 정렬할 수 있다. -create_date는 작성 일시가 저장되어있는 create_date 속성을 역순으로 정렬하라는 뜻이다.

아래 render 함수는 파이썬 데이터를 템플릿에 적용하여 HTML로 반환하는 함수이다. 즉, question_list 데이터를 notes/question_list.html 파일에 적용하여 HTML을 리턴한다.

 

2. 템플릿 디렉터리

템플릿을 작성하기 전에 템플릿 파일을 저장할 디렉터리를 먼저 만들어야 한다.

setting.py에서 TEMPLATES 항목을 다음과 같이 수정한다. DIRS에는 리스트로 되어있어 여러 템플릿 디렉터리를 등록할 수 있다.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

 

이제 터미널에 프로젝트 경로에서 mkdir templates를 입력하여 templates 디렉터리를 생성하자.

templates 내에 app 이름과 동일한 폴더를 만들어준다.

 

▶ 모든 앱이 공통으로 사용할 템플릿 디렉터리 - C:\projects\mysite\templates
▶ notes 앱만 사용할 템플릿 디렉터리 - C:\projects\mysite\templates\notes

 

3. 템플릿 파일

그리고 templates의 notes 디렉터리에 html 파일을 생성하고 다음과 같이 작성한다.

{% if question_list %}
    <ul>
    {% for question in question_list %}
        <li><a href="/notes/{{ question.id }}/">{{ question.subject }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}

위에서 {% 와 %}로 둘러싸인 부분을 템플릿 태그라고 한다.

 

템플릿 태그의 유형은 3가지로 나눌 수 있다.

1) 분기문(if문)

{% if 조건문1 %}
    <p>조건문1에 해당되는 경우</p>
{% elif 조건문2 %}
    <p>조건문2에 해당되는 경우</p>
{% else %}
    <p>조건문1, 2에 모두 해당되지 않는 경우</p>
{% endif %}

파이썬 문법과 거의 동일하고, {%와 %}로 둘러싸여있다는 것만 다르다. 꼭 {% endif %} 태그로 닫아주어야한다.

 

2) 반복

{% for item in list %}
    <p>순서: {{ forloop.counter }} </p>
    <p>{{ item }}</p>
{% endfor %}

마찬가지로 파이썬 문법과 동일하고, 꼭 {% endfor %} 태그로 닫아주어야한다.

 

3) 객체 출력

{{ 객체 }}
ex) {{ item }}

객체를 출력하기 위한 태그 사용법은 위와 같고, 객체의 속성이 있는 경우 {{ 객체.속성 }}으로 작성하면 된다. (ex. {{ question.id }})

 

4. URL 매핑

데이터가 여러개일 경우 http://localhost:8000/notes/1/, http://localhost:8000/notes/2/와 같이 페이지에 대한 url 매핑을 설정해주어야한다.

 

notes/urls.py 파일을 다음과 같이 수정한다.

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index),
    path('<int:question_id>/', views.detail),
]

 

5. views.py에 URL 매핑을 도와주는 함수 작성

urls.py에 URL 매핑을 추가했다. 이제 이 URL 매핑 시 question_id를 전달해주는 detail 함수를 작성해주어야한다. notes/views.py 파일에 detail 함수를 추가하고 다음과 같이 작성한다.

def detail(request, question_id):
    question = Question.objects.get(id=question_id)
    context = {'question': question}
    return render(request, 'notes/question_detail.html', context)

detail 함수 호출 시 question_id에 해당하는 데이터를 조회해서 return 해준다.

 

6. 특정 데이터를 출력하는 question_detail.html 작성

그리고 question_detail.html 템플릿을 아래와 같이 작성한다.

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

<div>
    {{ question.content }}
</div>

 

이제 다시 서버를 실행한 뒤 브라우저로 접속해보면 작성했던 질문 2개가 잘 뜨는 것을 확인할 수 있고, 질문 클릭 시 제목과 내용이 뜨며 url에 id 값을 잘 매핑하는 것을 볼 수 있다.

7. 오류 페이지 처리

id 값이 존재하지 않는 30번을 입력해보면, 아래와 같이 DoesNotExist 오류가 발생한다. 하지만, 이러한 오류페이지 보다는 "Not Found(404)" 페이지를 리턴하는 것이 바람직할 것이다.

HTTP 주요 응답코드의 종류는 다음과 같다.

오류코드 설명
200 성공 (OK)
500 서버오류 (Internal Server Error )
404 서버가 요청한 페이지(Resource)를 찾을 수 없음 (Not Found)

이 404 페이지를 출력하도록 하기 위해선, 앞에서 question_id 값을 urls.py로 전달해주도록 작성한 detail 함수를 수정해주어야한다.

detail 함수의 Question.objects.get(id=question_id)get_object_or_404(Question, pk=question_id)로 수정한다. 여기서 사용한 pk는 Question 모델의 기본키(Primary Key)인 id를 의미한다.

이제 아래와 같이 404 페이지가 출력되는 것을 확인할 수 있다.

 

참고: https://wikidocs.net/70736

728x90
반응형