python/Django

[Django] 6. 장고 템플릿 구현

끼발자 2021. 12. 22. 14:04
반응형

이번엔 질문과 답변을 템플릿을 이용해서 만들어보자.

 

#pybo/views.py

from django.http import HttpResponse # http의 응답
from .models import Question

def index(request):
    '''
    pybo 목록 출력
    '''
    question_list = Question.objects.order_by('-create_date') # -로 역순
    context = {'question_list':question_list}
    return render(request,'pybo/question_list.html',context) # 연결되는 html, 전달할 매체 context

render를 이용해서 context에 key : value로 있는 question_list 데이터를 html로 넘겨준다.

 

이제 이 html이 담겨있는 디렉터리를 구성해보자.

 

장고 프로젝트 디렉터리 바로 아래에 templates라는 폴더를 생성하고, config/settings.py 을 열어서 수정하자

#config/settings.py 
...
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',
            ],
        },
    },
]
...

템플릿의 경로에 templates를 넣어주자.

 

BASE_DIR은 프로젝트가 위치하는 디렉터리이다.

 

장고에서 사용하는 모든 템플릿은 templates 에 담고, 서비스별로 하위 디렉터리를 만들어 관리한다.

 

ex) 공통 템플릿 : BASE_DIR/templates/layout.html , pybo 템플릿 : BASE_DIR/templates/pybo/~~~.html

 

그러면 이제 템플릿 디렉터리 아래에 pybo라는 디렉터리를 생성하고, question_list.html이름으로 html파일을 생성하자.

 

내용은 다음과 같다.

 

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

 

처음 템플릿 태그를 보면 어질어질하다.

 

{% %} 내부에 변수가 적용된다.

 

즉 {% if question_list %} 파이썬에서도 if question_list 라고 입력하면 비어있는지 / 채워져있는지에 대한 bool이 반환된다.

 

question_list가 있으면 아래의 구문을 실행. 반복문은 파이썬과 동일하고,

 

{{question.id}}는 question객체에서 id를 의미한다. 다만 주의할 사항은 반복문과 조건문이 끝날 때, {% endfor %} {% endif %}등을 적어줘야한다.

 

저렇게 템플릿까지 만들었다면 이제 pybo에 접속해보자

 

물론 저 링크를 누르면 404페이지가 나온다.

 

링크를 누르면 /pybo/2/ 이렇게 이동이되는데, 저 url에 대한 정보를 만들어주지 않았기 때문이다.

 

# pybo/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('',views.index),
    path('<int:question_id>/', views.detail),  # 가변적인 endpoint, question.id의 타입은 int이다.
]

url을 매핑해주고 연결되는 함수는 views의 detail 함수에 연결되도록 하자.

/pybo/1 or /pybo/2 ... 이런식으로 pybo다음에 오는 숫자는 가변적이며, question_id라는 이름으로 views.detail에 전달된다.

 

# pybo/views.py
def detail(request,question_id):
    '''
    pybo 내용 출력
    '''
    question = Question.objects.get(id = question_id)    
    context = {'question':question}
    return render(request,'pybo/question_detail.html',context)

index함수와 크게 다르진 않아보이지만, detail에는 전달하는 파라미터가 question_id로 하나 더 생겼다.

 

url에서 question_id를 전달해주기 때문에, 이를 받아서 데이터를 찾고 html로 넘겨준다.

 

이제 question_detail.html을 작성하자.

 

templates/pybo/question_detail.html

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

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

 

 

자 질문 상세화면이 출력되었다.

반응형