티스토리 뷰

 

오늘은 Flask를 기반으로 한 Q&A 웹 애플리케이션인 파이보(Pybo) 프로젝트 개발 실습을 진행했습니다.
질문과 답변을 주고받을 수 있는 기능을 구현하면서, 실제 서비스 개발 흐름과 구조를 익히는 데 집중했습니다.
템플릿 상속, 폼 처리, URL 연결, DB 모델링 등 Flask로 웹서비스를 구축하는 전 과정을 경험할 수 있었습니다.


1. 프로젝트 구성

파이보 프로젝트는 다음과 같은 구조로 구성됩니다.

pybo/
├── __init__.py
├── views/
│   ├── base_views.py
│   ├── question_views.py
│   └── answer_views.py
├── models.py
├── forms.py
templates/
├── base.html
├── index.html
├── question/
│   ├── question_detail.html
│   └── question_form.html
├── answer/
│   └── answer_form.html
static/
├── style.css

2. 질문 목록 출력

메인 페이지에서 질문 목록을 출력하는 기능을 구현합니다.

  • base_views.py에서 메인 페이지 라우트를 구성하고
  • index.html 템플릿에서 질문 리스트를 반복문으로 출력합니다.
@bp.route('/')
def index():
    question_list = Question.query.order_by(Question.create_date.desc())
    return render_template('index.html', question_list=question_list)

3. 질문 상세 보기

질문을 클릭하면 해당 질문의 상세 페이지로 이동합니다.

@bp.route('/detail/<int:question_id>/')
def detail(question_id):
    question = Question.query.get_or_404(question_id)
    return render_template('question/question_detail.html', question=question)

4. 질문 등록 기능

  • question_views.py에서 /create/ 라우트를 만들어
  • QuestionForm을 이용해 질문 등록을 처리합니다.
@bp.route('/create/', methods=('GET', 'POST'))
def create():
    form = QuestionForm()
    if request.method == 'POST' and form.validate_on_submit():
        question = Question(subject=form.subject.data, content=form.content.data, create_date=datetime.now())
        db.session.add(question)
        db.session.commit()
        return redirect(url_for('main.index'))
    return render_template('question/question_form.html', form=form)

5. 답변 등록 기능

질문 상세 페이지에서 답변을 입력할 수 있는 폼을 만들고, 해당 질문에 대한 답변을 저장합니다.

@bp.route('/create/<int:question_id>/', methods=('POST',))
def answer_create(question_id):
    form = AnswerForm()
    question = Question.query.get_or_404(question_id)
    if form.validate_on_submit():
        answer = Answer(content=form.content.data, create_date=datetime.now(), question=question)
        db.session.add(answer)
        db.session.commit()
        return redirect(url_for('main.detail', question_id=question_id))
    return render_template('question/question_detail.html', question=question, form=form)

6. 질문/답변 수정 및 삭제 기능

각 질문과 답변에는 수정 및 삭제 기능을 추가합니다.

질문 수정

@bp.route('/modify/<int:question_id>/', methods=('GET', 'POST'))
def modify(question_id):
    question = Question.query.get_or_404(question_id)
    form = QuestionForm(obj=question)
    if request.method == 'POST' and form.validate_on_submit():
        form.populate_obj(question)
        db.session.commit()
        return redirect(url_for('main.detail', question_id=question_id))
    return render_template('question/question_form.html', form=form)

질문 삭제

@bp.route('/delete/<int:question_id>/')
def delete(question_id):
    question = Question.query.get_or_404(question_id)
    db.session.delete(question)
    db.session.commit()
    return redirect(url_for('main.index'))

답변 수정/삭제도 유사한 방식으로 answer_views.py에 구현합니다.


7. 템플릿 상속과 부트스트랩 적용

모든 페이지는 base.html을 상속받아 공통 구조를 유지합니다.

{% extends 'base.html' %}

{% block content %}
<h1>{{ question.subject }}</h1>
<p>{{ question.content }}</p>
...
{% endblock %}

부트스트랩을 활용해 템플릿 디자인을 개선하고, static/style.css로 직접 스타일도 설정했습니다.


8. URL 연결 및 리디렉션

  • url_for()를 사용해 라우트를 템플릿과 연결
  • redirect()로 등록 후 상세 페이지나 목록으로 이동 처리
return redirect(url_for('main.index'))
return redirect(url_for('main.detail', question_id=question.id))

9. 폼 클래스 분리

  • forms.py에 QuestionForm, AnswerForm을 정의해 관리
  • 템플릿에서도 form.field 형태로 깔끔하게 폼을 표시

10. 기타 기능들

  • 답변이 여러 개일 때 리스트 형태로 출력
  • 날짜 포맷 필터링 (strftime 활용)
  • HTML 태그 이스케이프 처리 (| safe)

11. 결론 및 정리

오늘은 Flask를 활용해 Q&A 웹 서비스인 Pybo를 직접 개발하면서 웹 프로젝트의 전체 흐름을 경험했습니다.
라우팅, 템플릿 렌더링, 폼 처리, DB 연동, CRUD 기능 구현까지 실제 서비스에 필요한 전반적인 요소를 배웠고,
단순한 예제 수준을 넘어서 실제 서비스 구조를 설계하는 감각도 키울 수 있는 유익한 시간이었습니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함