[Flask] 질문 목록과 질문 상세 기능 만들기

참조


질문 목록 기능 만들기

  • 지금 만들어야 하는 질문 목록 기능은 다음 주소에 접속할 때 동작해야 합니다.
  • 플라스크 서버를 실행하고 웹 브라우저에서 localhost:5000 에 접속합니다.
  • "Pybo index" 라는 문구가 출력되는 것을 확인할 수 있습니다.


게시판 질문 목록 출력하기

  • 위 화면 대신 게시판 질문 목록이 출력되도록 main_view.py 파일을 수정합니다.
  • index 함수가 문자열을 반환하던 부분을 질문 목록을 출력하도록 변경합니다.
from flask import Blueprint, render_template
from pybo.models import Question

bp = Blueprint('main', __name__, url_prefix='/')

@bp.route('/hello')
def hello_pybo():
    return 'Hello, Pybo!'

@bp.route('/')
def index():
    question_list = Question.query.order_by(Question.create_date.desc())
    return render_template('question/question_list.html', question_list=question_list)
  • 질문 목록 데이터는 question_list=Qustion.query.order_by(Question.create_date.desc()) 로 얻을 수 있습니다.
  • order_by는 조회 결과를 정렬하는 함수 입니다.
  • render_template 함수는 템플릿 파일을 화면으로 렌더링 하는 함수입니다.
  • 조회된 질문 목록 데이터를 render_template 함수의 파라미터로 전달하여 템플릿에서 해당 데이터로 화면을 구성합니다.
  • 여기서 사용된 question/question_list.html 파일을 템플릿 파일이라고 부릅니다.

질문 목록 템플릿 파일 작성하기

  • 이제 render_template 함수에서 사용할 question/question_list.html 템플릿 파일을 작성해야 합니다.
  • 해당 파일은 플라스크 앱으로 지정한 모듈 아래에 templates 라는 디렉터리에 저장합니다.
  • 그러면 별 다른 설정 없이도 templates 디렉터리에 템플릿 디렉터리로 인식합니다.
  • 아래 명령을 통해 pybo 앱 디렉터리 아래에 templates 디렉터리를 생성합니다.

    템플릿 파일은 쉽게 말해 파이썬 문법을 사용할 수 있는 HTML 파일입니다. 템플릿 파일은 HTML 파일과 비슷 하지만 플라스크의 특별한 태그를 사용할 수 있습니다.

(myproject) C:\venvs\myproject>cd pybo
(myproject) C:\venvs\myproject\pybo>mkdir templates
  • 템플릿 디렉터리가 준비되었으므로 이제 해당 디렉터리에 템플릿 파일을 생성합니다.
  • render_template 함수에 지정한 템플릿 파일명은 question/question_list.html 이므로 이 이름으로 템플릿 파일을 생성하고 아래와 같이 코드를 작성합니다.
{% if question_list %}
    <ul>
    {% for question in question_list %}
        <li><a href="/detail/{{ question.id }}/">{{ question.subject }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}
  • 템플릿 파일에 입력된 {% if question_list %} 와 같은 특이한 표현이 있습니다.
  • {% 와 %} 로 둘러싸인 문장을 템플릿 태그라고 합니다.
  • 이 태그가 파이썬 코드와 연결됩니다.
{% if question_list %}
  • 위 코드는 render_template 함수에서 전달받은 질문 목록 데이터 question_list 가 있는지 검사합니다.
{% for question in question_list %}
  • 위 코드는 question_list에 저장된 데이터를 하나씩 꺼내 question 객체에 대입합니다.
{{question.id}}
  • 위 코드는 바로 앞의 for 문에서 얻은 question 객체의 id를 출력합니다.
  • {{question.subject}} 코드도 같은 맥락으로 이해하시면 도비니다.
  • 다시 서버를 실행하고 웹 브라우저에서 localhost:5000 으로 접속하여 결과 확인합니다.


질문 상세 기능 만들기

  • 앞에서 만든 질문 목록 페이지에서 질문 링크(Flask ModelQuestion) 눌러보면 다음과 같은 오류 메시지가 표시됩니다.
  • 해당 오류는 주소 표시줄에 보이는 localhost:5000/detail/2 페이지의 URL을 정의하지 않아 발생한 것입니다.
  • 해당 문제 해결 방법은 다음과 같습니다.


라우트 함수 구현하기

  • 질문 목록에서 링크를 누르면 다음과 같은 질문 상세 URL을 요청합니다.
localhost:5000/detail/2/
  • 이 URL은 "Question" 모델 데이터 중 id 값이 2인 데이터를 조회하라 는 의미입니다.
  • 이와 같은 요청 URL에 대응할 수 있도록 main_view.py 파일에 @bp.route 와 함께 detail 함수를 추가합니다.
from flask import Blueprint, render_template
from pybo.models import Question

bp = Blueprint('main', __name__, url_prefix='/')

@bp.route('/hello')
def hello_pybo():
    return 'Hello, Pybo!'

@bp.route('/')
def index():
    question_list = Question.query.order_by(Question.create_date.desc())
    return render_template('question/question_list.html', question_list=question_list)

@bp.route('/detail/<int:qeustion_id>/')
def detail(question_id):
    question = Question.query.get(question_id)
    return render_template('question/question_detail.html', question=question)
  • detail 함수의 매배견수 question_id 에는 라우트 매핑 규칙에 사용한 <int:question_id> 가 전달됩니다.
  • 즉, localhost:5000/detail/2/ 페이지를 요청하면 main_views.py 파일의 detail 함수가 실행되고, 매개변수 question_id 에는 2라는 값이 전달됩니다.

질문 상세 템플릿 작성하기

  • 질문 상세 화면에 해당하는 question/question_detail.html 템플릿을 작성합니다.
  • templates/question 디렉터리에 question_detail.html 파일을 만들고 아래 코드를 작성합니다.
<h1>{{ question.subject }}</h1>

<div>
    {{ question.content }}
</div>
  • {{question.subject}}{{question.content}} 의 question은 render_template 함수에 전달한 질문 객체 입니다.
  • localhost:5000/detail/2/ 페이지를 다시 요청한 결과 에러 없이 실행되는 것을 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY