Django 웹사이트 만들기 7. 답변 등록 기능 만들기
앞서 만든 질문에 답변을 달하주는 기능을 만들어보자.
1-1. 질문 상세 템플릿(pyweb/question_detail)에 답변 등록 버튼 만들기
form 엘리먼트 안에 textarea 엘리먼트와 input 엘리먼트를 포함시켜 답변 내용, 답변 등록 버튼을 추가한다.
<h1>{{ question.subject }}</h1>
<div>
{{ question.content }}
</div>
<form action="{% url 'pyweb:answer_create' question.id %}" method="post">
{% csrf_token %}
<textarea name = "content" id ="content" rows=""15"></textarea>
<input type="submit" value="답변 등록">
</form>
답변 등록 버튼을 누르면 URL은 action 속성에 있는 {% url 'pyweb:answer_create' question.id %}이다.
{% csrf_token %}은 보안관련 항목인데, form엘리먼트를 통해 전송된 데이터(답변)가 실제로 웹브라우저에서 작성된 데이터인지 판단하는 검사기 역할을 한다.
1-2. pyweb/urls.py에 답변 등록을 위한 URL 매핑 등록하기
from django.urls import path
from . import views
app_name = 'pyweb'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('answer/create/<int:question_id>/', views.answer_create, name='answer_create'),
]
1-3. pyweb/views.py에 answer_create 항수 추가하기
from django.shortcuts import render, get_object_or_404
from .models import Question
from django.utils import timezone
...생략...
def answer_create(request, question_id):
"""
pyweb 답변등록
"""
question = get_object_or_404(Question, pk=question_id)
question.answer_set.create(content=request.POST.get('content'),
create_date=timezone.now())
answer_create 함수의 question_id 매개변수에는 URL매핑 정보값이 넘어온다. request 매개변수에는 pyweb/question_detail.html의 textarea에 입력된 데이터가 파이썬 객체에 담겨 넘어오고 이 값을 추출하기 위한 코드가 request.POST.get('content')이다.
Question모델을 통해 Answer모델 데이터를 생성하기 위해 question.answer_set.create을 사용했다.
1-4. 답변등록 후 상세 화면으로 이동하기
답변을 생성한 뒤 상세 화면을 호출하려면 redirect 함수를 사용한다. redirect 함수는 함수에 전달된 값을 참고하여 페이지 이동을 수행한다.
redirect함수의 첫번째 인수에는 이동할 페이지의 별칭을, 두번째 인수에는 URL에 전달해야 하는 값을 입력한다.
from django.shortcuts import render, get_object_or_404, redirect ##추가
from .models import Question
from django.utils import timezone
def answer_create(request, question_id):
"""
pyweb 답변등록
"""
question = get_object_or_404(Question, pk=question_id)
question.answer_set.create(content=request.POST.get('content'),
create_date=timezone.now())
return redirect('pyweb:detail', question_id=question.id) ##추가
아래의 답변 등록 버튼을 눌러도 아무 이벤트가 발생하지 않을텐데, 등록된 답변을 표시하는 기능을 추가하지 않았기 때문이다.
1-5. pyweb/question_detail.html 수정하여 등록된 답변 표시하기
<h1>{{ question.subject }}</h1>
<div>
{{ question.content }}
</div>
##추가
<h5>{{ question.answer_set.count }}개의 답변의 있습니다.</h5>
<div>
<ul>
{% for answer in question.answer_set.all %}
<li>{{ answer.content }}</li>
{% endfor %}
</ul>
</div>
<form action="{% url 'pyweb:answer_create' question.id %}" method="post">
{% csrf_token %}
<textarea name="content" id="content" rows="15"></textarea>
<input type="submit" value="답변 등록">
</form>
질문 상세 페이지에 접속하면 다음과 같은 화면을 볼 수 있다.