반응형

답변 등록 폼을 추가해 Flask-WTF을 이용하도록 수정하겠습니다.

 

from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired


class QuestionForm(FlaskForm):
    subject = StringField('제목', validators=[DataRequired('제목은 필수 입력 항목입니다.')])
    content = TextAreaField('내용', validators=[DataRequired('내용은 필수 입력 항목입니다.')])

class AnswerForm(FlaskForm):
    content = TextAreaField('내용', validators=[DataRequired('내용은 필수 입력 항목입니다.')])

forms.py 입니다.

 

AnswerForm을 추가시켜서 댓글 작성란에 무조건 입력을 해야하는 검증을 넣었습니다.

from datetime import datetime

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

from .. import db
from ..models import Question, Answer
from ..forms import AnswerForm

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

@bp.route('/create/<int:question_id>', methods=('POST', ))
def create(question_id):
    form = AnswerForm()
    question = Question.query.get_or_404(question_id) # 그 질문에 해당하는 번호를 가져온다.
    if form.validate_on_submit():
        content = request.form['content']  # name 속성이 content인 값
        answer = Answer(content=content, create_date=datetime.now())  # textArea 내용, 작성시각
        question.answer_set.append(answer)  # question.answer_set 은 Answer과 동일 즉, 거기에다가 값을 추가하는 것임
        db.session.commit()  # db에 저장
        return redirect(url_for('question.detail', question_id=question_id))  # 상세 질문과 답변이 있는 페이지로 전달
    return render_template('question/question_detail.html', question=question, form=form)

 

answer_views.py 입니다.

댓글 작성에 만약 form.validate_on_submit()으로 form 검증이 올바른 경우 댓글 등록하는 기능을 넣고

만약 올바르지 않던가 아무런 submit이 없으면 question_detail.html화면을 보여주게 했습니다.

 

from datetime import datetime

from flask import Blueprint, render_template, request, url_for
from ..models import Question
from werkzeug.utils import redirect
from .. import db

from ..forms import QuestionForm, AnswerForm

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

@bp.route('/list')
def _list():
    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:question_id>')
def detail(question_id):
    form = AnswerForm()
    question = Question.query.get_or_404(question_id)
    return render_template('question/question_detail.html', question=question, form=form)

@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)

question_views.py 입니다.

def detail 함수도 수정해줘야 합니다. form값을 보내야지 밑에 새로 정의할 내용

즉 error값에 대한 form값을 못 가져와서 에러를 내보내기 때문입니다.

 

여기에서 form은 댓글 내용이 잘 들어갔는지 확인하는 기능입니다.

<!DOCTYPE html>
<html lang="en">


<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    {% extends 'base.html' %}
    {% block content %}

    <div class="container my-3">
        <h2 class="border-bottom py-2">{{ question.subject }}</h2>
        <div class="card my-3">
            <div class="card-body">
                <div class="card-text" style="white-space: pre-line;">{{ question.content }}</div>
            </div>
            <div class="d-flex justify-content-end">
                <div class="badge badge-light p-2">
                    {{ question.create_date }}
                </div>
            </div>
        </div>


        <h5 class="border-bottom my-3 py-2">{{ question.answer_set|length }}개의 답변이 있습니다.</h5>
        {% for answer in question.answer_set %}
        <div class="card my-3">
            <div class="card-body">
                <div class="card-text" style="white-space : pre-line;">
                    {{ answer.content }}
                </div>
                <div class="d-flex justify-content-end">
                    <div class="badge badge-light p-2">
                        {{ answer.create_date }}
                    </div>
                </div>
            </div>
        </div>
        {% endfor %}

        <h5> {{ question.answer_set|length }}개의 답변이 있습니다. </h5>

        <div>
            <ul>
                {% for answer in question.answer_set %}
                    <li> {{ answer.content }}</li>
                {% endfor %}
            </ul>
        </div>

        <form class="my-3" action="{{ url_for('answer.create', question_id=question.id) }}" method="post">
          {{ form.csrf_token }}
          <!-- 오류표시 Start -->
          {% for field, errors in form.errors.items() %}
              <div class="alert alert-danger" role="alert">
                  <strong>{{ form[field].label }}</strong>: {{ ','.join(errors) }}
              </div>
          {% endfor %}
          <!-- 오류표시 End -->
            <div class="form-group">
                <textarea name="content" id="content" row="15"></textarea>
                <input class="btn btn-primary" type="submit" value="답변등록">
            </div>
        </form>
    </div>

    {% endblock %}
</body>
</html>

question_detail.html 입니다.

 

반응형