/question_detail.html
<form action="{% url 'review:answer_create' question.id %}" method="POST">
{% csrf_token %}
<textarea name="content" id="content" rows="15"></textarea>
<input type="submit" value="답변등록">
</form>
답변 내용을 적을 수 있는 textarea
와 답변을 등록하는 답변버튼
을 만들었다.
{% url 'review:answer_create' question.id %}
은 답변을 저장하는 URL이며 데이터를 보내는 방식은 POST
로 작성했다.
form
태그 바로 밑에 보이는 {% csrf_token %}
은 보안에 관련된 항목으로 form
으로 전송된 데이터가 실제 웹페이지에서 작성된 데이터인지를 판단해 주는 가늠자 역할을 한다. 기타 다른 해킹 툴등에 의해서 데이터가 전송될 경우에는 서버에서 발행한 csrf_token값과 해당 툴에서 보낸 csrf_token 값이 일치하지 않기때문에 오류가 발생한다.
따라서 form태그 바로 밑에 {% csrf_token %} 을 항상 위치시키도록 해야 한다.
위와 같은 상태로 로컬 서버를 구동하고 상세페이지를 들어가보면 다음과 같은 에러가 발생한다.
answer_create
를 아직 만들어주지 않았기 때문에 발생하는 에러이기 때문에, 이부분을 추가해줘야한다.
/review/urls.py
path("answer/create/<int:question_id>/", views.answer_create, name="answer_create"
이제 views.py
에서 answer_create
함수를 작성해주면 URL매핑이 끝난다.
from django.shortcuts import redirect
from django.utils import timezone
def answer_create(request, question_id):
question = get_object_or_404(Question, pk=question_id)
question.answer_set.create(content=request.POST.get("content"), create_date=timezone.now())
return redirect("review:detail", question_id=question.id)
답변을 생성한 후 상세조회 화면을 호출하기 위해 redirect
함수를 사용했다. redirect
함수는 페이지 이동을 위해 장고가 제공하는 함수이다. 여기서는 답변 저장 후 pybo:detail 페이지로 이동하기 위해 사용되었다.
첫번째 매개변수 request
객체를 통해 폼에서 입력한 답변 데이터를 읽을 수 있다. request.POST.get('content')
는 POST로 전송된 폼(form) 데이터 항목 중 content의 값을 의미한다.
그리고 답변을 생성하기 위해 question.asnswer_set.create
를 사용하였다. question.answer_set
은 질문의 답변을 의미한다. Question
과 Answer
모델은 서로 ForeignKey
로 연결되어 있기때문에 이처럼 사용할 수 있다.
❗️답변을 저장하는 또 다른 방법은 다음처럼 Answer 모델을 직접 사용하는 방법이다.
question = get_object_or_404(Question, pk=question_id)
answer = Answer(question=question, content=request.POST.get('content'), create_date=timezone.now())
answer.save()
redirect('pybo:detail', question_id=question.id)
에서 사용된 question_id
는 다음과 같이 정의된 URL매핑에 question_id
를 전달하기 위해 필요하다.
path('<int:question_id>/', views.detail, name='detail'),
메인화면에서 상세화면을 누르면 이런 화면이 이제 나타난다.
답변을 등록할 수 있는 구역에 글을 작성하고 답변을 등록해보아도 아직 보여줄 템플릿을 수정하지 않았기 때문에 에러가 발생한다.😂 템플릿을 마저 수정해주자..
/templates/review/question_detail.html
<h5>{{ question.answer_set.count }}개의 답변이 있습니다.</h5>
<div>
<ul>
{% for answer in question.answer_set.all %}
<li>
{{ answer.content }}
</li>
{% endfor %}
</ul>
</div>
question.answer_set.count
를 통해 질문에 달린 답변의 갯수를 카운트해서 표시해주었다. qeustion.answer_set.all
는 질문에 달린 답변의 전체인데 이 전체를 반복문을 통해 answer
에 순차적으로 넣어주었고, <li>
태그를 사용해 이 순차적으로 넣은 answer
의 content
를 표시해주었다.
이제 다시 답변을 등록해보자.
이런식으로 답변이 제대로 달리며, 답변을 추가할때마다 답변의 갯수도 함께 증가하는것을 확인할 수 있다.