[Flask] 답변 등록 기능 만들기

참조


소개

  • 질문 상세 화면에 답변을 입력하기 위한 텍스트 창(textarea) 과 <답변등록> 버튼을 생성하고, 이 버튼을 누르면 텍스트 창에 입력 된 데이터가 저장되도록 구현합니다.

답변 등록 버튼 만들기

  • 질문 상세 템플릿에 답변 저장을 위한 form, textarea, input 엘리먼트를 추가합니다.
<h1>{{ question.subject }}</h1>

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

<form action="{{ url_for('answer.create', question_id=question.id) }}" method="post">
    <textarea name="content" id="content" rows="15"></textarea>
    <input type="submit" value="답변등록">
</form>
  • 답변 저장 URL은 form 태그의 action 속성에 지정된 url_for('answer.create', question_id=question.id) 가 알려줍니다.
  • 이후 <답변등록> 버튼을 클릭하면 POST 방식으로 이 URL이 호출 됩니다.
  • 코드를 추가한 후 웹 브라우저에서 질문 상세페이지를 요청합니다.
  • 그러면 URL을 찾을 수 없다는 오류 메시지가 나오게 됩니다.
  • 해당 오류를 해결하려면 답변 모델에 해당하는 블루프린트 파일을 작성하고 create 함수를 만들어야 합니다.


답변 블루프린트 만들기

  • question 블루프린트를 만들었듯이, answer 블루프린트를 생성합니다.
  • answer_views.py 파일을 만들고 아래 코드처럼 작성합니다.
from datetime import datetime

from flask import Blueprint, url_for, request
from werkzeug.utils import redirect

from pybo import db
from pybo.models import Question, Answer

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

@bp.route('/create/<int:question_id>', methods=('POST',))
def create(question_id):
    question = Question.query.get_or_404(question_id)
    content = request.form['content']
    answer = Answer(content=content, create_date=datetime.now())
    question.answer_set.append(answer)
    db.session.commit()
    return redirect(url_for('question.detail', question_id=question_id))
  • create 함수의 매개변수 question_id 는 URL에서 전달 됩니다.
  • 만약 localhost:5000/answer/create/2/ 페이지를 요청 받으면 question_id 에는 2가 넘어 옵니다.
  • @bp.route의 methods 속성에는 'POST' 를 지정해 주었습니다.

답변 블루프린트 적용하기

  • answer_views.bp를 pybo/init.py 파일에 등록합니다.
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

import config

db = SQLAlchemy()
migrate = Migrate()

def create_app():
    app = Flask(__name__)
    app.config.from_object(config)

    # ORM
    db.init_app(app)
    migrate.init_app(app, db)
    from . import models

    # 블루프린트
    from .views import main_views, question_views, answer_views
    app.register_blueprint(main_views.bp)
    app.register_blueprint(question_views.bp)
    app.register_blueprint(answer_views.bp)

    return app
  • 질문 상세 페이지에 접속하게 되면, 답번등록 버튼이 생성된 것을 확인할 수 있습니다.


질문 상세 페이지에 답편 표시하기

  • 질문에 등록된 답변을 화면에 표시해 보는 코드를 다음과 같이 추가합니다.
<h1>{{ question.subject }}</h1>

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

<h5>{{ question.answer_set|length }}개의 답변이 있습니다.</h5>
<div>
    <ul>
    {% for answer in question.answer_set %}
        <li>{{ answer.content }}</li>
    {% endfor %}
    </ul>
</div>

<form action="{{ url_for('answer.create', question_id=question.id) }}" method="post">
    <textarea name="content" id="content" rows="15"></textarea>
    <input type="submit" value="답변등록">
</form>
  • 기존 코드에서 답변을 확인할 수 있는 영역을 추가했습니다.
  • {{question.answer_set|length}} 코드는 답변 개수를 의미합니다.
  • length는 템플릿 필터인데 객체의 길이를 반환해줍니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY