새소식

python/Django

Django - mysite (조회와 템플릿)

  • -

링크

이 페이지의 내용 정리 위캔입니다.
완성 소스 깃 허브

질문 목록

  • localhost:8000/pybo 에 접속 시 등록한 질문들을 조회할 수 있도록 구현
  • pybo/views.py 수정
 # 삭제 from django.http import HttpResponse
# 추가
from django.shortcuts import render
form .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)
  • 질문 목록 데이터는 Question.objects.order_by('-create_date')로 얻을 수 있다.
    • order_by는 조회 결과를 정렬하는 함수
    • order_by(-create_date)는 작성일시 역순으로 정렬하라는 의미 (-가 없으면 순방향)
  • render 함수는 파이썬 데이터를 템플릿에 적용하여 HTML로 반환하는 함수이다.
  • 위에서 사용한 return render(request, 'pybo.question_list.html', context)
    • question_list 데이터를 pybo/question_list.html 파일에 적용하여 HTML을 리턴한다.
      • 여기서 사용한 pybo/question_list.html과 같은 파일을 템플릿이라고 부른다.
      • 템플릿 파일은 장고에서 사용하는 태그를 사용할 수 있는 HTML파일이다.템플릿 디렉터리
  • 템플릿 파일 작성 전에 템플릿 파일을 저장할 디렉터리 생성
  • config/settings.py 파일의 TEMPLATES 항목에 추가
...
TEMPLATES = [
        {
            'BACKEND' : 'django.template.backends.django.DjangoTemplates',
            # 수정
            'DIRS' : [BASE_DIR / 'templates'],
            'APP_DIRS' : True,
            ...
        }
    ]
...
  • DIRS 는 템플릿 디렉터리를 여러 개 등록할 수 있도록 리스트로 되어있다.
  • 파이보는 BASE_DIR / 'templates' 디렉터리만 등록
  • BASE_DIR...Django_projects\site2 이므로 추가한 디렉토리 경로는 ...Django_projects\site2\templates이다.
  • ...Django_projects\site2\templates디렉터리는 존재하지 않으므로 생성한다.
    • ...Django_projects\site>mkdir templates
    • 장고는 DIRS에 설정한 디렉터리 외에도 앱 디렉터리 바로 하위에 있는 templates 디렉터리도 템플릿 디렉터리로 이해한다.
      • 즉 pybo 앱의 경우 다음의 디렉터리를 생성하면 템플릿 디렉터리로 인식한다. (...Django_projects\site2\pybo\templates)
        • 모든 앱이 공통으로 사용한 템플릿 디렉터리 - ...Django_projects\site2\templates
        • pybo앱만 사용할 템플릿 디렉터리 - ...Django_projects\site2\templates\pybo

 

템플릿 파일

  • ...Django_projects\site2\templates\pyboquestion_list.html 파일 저장
  • render 함수에서 사용한 pybo/question_list.html 템플릿 파일 작성
{% if question_list %} <!--question_list가 있다면 question_list는 render 함수로 전달받은 질문 목록 데이터이다.-->
    <ul>
        {% for question in question_list %} <!--for문으로 question_list를 question에 순차적으로 대입-->
        <li><a href="/pybo/{{question.id}}/">{{question.subject}}</a></li>
        <!--question.id 는 for문으로 대입된 question의 id번호 출력, question.subject는 제목 출력-->
        {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}

 

템플릿 태그

  • 3가지 유형
  1. 분기
{% if 조건문1 %}
    <p>조건문1에 해당되는 경우</p>
{% elif 조건문2 %}
    <p>조건문2에 해당되는 경우</p>
{% else %}
    <p>조건문1, 2에 모두 해당되지 않는 경우</p>
{% endif %}

python의 if문과 같다.
항상 {% endif %} 태그로 닫아주어야 한다.
2. 반복

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

python의 for문과 같다.
항상 {% endif %} 태그로 닫아주어야 한다.
3. 객체 출력
{{ 객체이름 }}

  • 객체에 속성이 있는 경우
    {{ 객체이름.속성 }}

질문 상세

  • 현재 페이지에서 질문의 상세보기를 하면 오류가 발생한다.
  • http://localhost:8000/pybo/2/와 같은 페이지에 대한 URL 매핑이 아직 없기 때문이다.urls.py
  • http://localhost:8000/pybo/2/ 이 URL의 의도는 'id 값이 2인 Question을 상세조회한다.'이다.
  • 위의 URL이 동작할 수 있도록 urls.py 파일을 수정한다.
  • 경로는 ...config\urls.py 가 아닌 ...pybo\urls.py이다.
from django.urls import path

...
urlpatterns = [
    path('', views.index),
    # 추가
    path('<int : quesiton_id>/', views.detail),
    # int는 숫자가 매핑됨을 의미한다.
]
  • path('<int:question_id>/', views.detail)이라는 URL 매핑을 추가하였다.
  • 이제 페이지에서 질문의 상세보기를 하면 위 매핑 룰에 의해 question_id가 저장되고 view.detail 함수가 실행된다.views.py
  • urls.py에서 사용하는 views.detatil 함수를 생성해야 한다.
  • views.py 파일에 detail 함수 추가
...
# 추가
def detail(request, question_id):
    '''
    pybo 내용 출력
    '''
    question = Question.object.get(id = question_id)
    context = {'quesiton' : question}
    return context renter(request, 'pybo/question_detail.html', context)

quesiton_detail.html

  • question_detail.html 템플릿 작성
<h1>{{question.subject}}</h1>

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

오류 페이지

  • http://localhost:8000/pybo/30/을 요청하면 저장되어있는 id보다 요청값이 더 크기 때문에 오류가 발생한다.
  • 존재하지 않는 데이터를 요청할 경우 404페이지(not Found)를 출력하도록 detail 함수 수정
  • 경로 : ...pybo\views.py
# 수정
from django.shortcuts import render, get_object_or_404
...

def detail(request, question_id):
...
# 수정
question = get_object_or_404(Question, pk=question_id)
# pk는 Question 모델의 기본키(primary Key)인 id를 의미한다.
...
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.