링크
이 페이지의 내용 정리 위캔입니다.
답변 등록 폼
- 경로 :
... templates\pybo\question_detail.html
<h1>{{question.subject}}</h1>
<div>
{{question.content}}
</div>
<form action="{% url 'pybo:answer_create' question.id %}" method = "post"> <!--action은 답변 저장을 위한 태그이다.-->
{% csrf_token %} <!-- form으로 전송한 데이터가 실제 웹페이지에서 작성한 데이터인지를 판단해주는 역할-->
<!--만약 해커가 엉뚱한 방법으로 데이터를 전송할 경우 서버에서 발행한 csrf_token 값과 해당 툴에서 보내는 csrf_token 값이 일치하지 않기 때문에 오류가 발생한다.-->
<!--위와 같은 이유로 form 태그 바로 밑에는 항상 {# csrf_token %} 태그를 위치 시킨다.-->
<textarea name="content" id="content" rows="15"></textarear> <!--답변을 입력할 수 있는 텍스트 창-->
<input type="submit" value="답변 등록"> <!--답변을 저장할 수 있는 버튼-->
</form>
- 답변의 내용을 입력할 수 있는 텍스트창과 답변을 저장할 수 있는 "답변등록" 버튼을 추가했다.
- 답변 저장을 위한 URL은 form 태그의 action 속성에
{% url 'pybo:answer_create' question.id %}
로 지정했다.
URL 매핑
- 지금 상태로 질문 상세페이지를 접속하면 오류가 발생한다.(
answer_create
별칭을 찾을 수 없다는 오류)
question_detail.html
에 {% url 'pybo:answer_create' question_id}
와 같은 별칭을 사용했기 때문
- 경로 :
...pybo\urls.py
urlpatterns = [
...
# 추가
path('answer/create/<int:question_id>/', views.answer_create, name='answer_create'),
]
- 이제
http://locahost:8000/pybo/answer/create/2/
와 같은 페이지를 요청하면 views.answer_create
함수가 호출된다.
뷰 함수
- 경로 :
...pybo\views.py
1번째 방법
# 수정
form django.shorcuts import renter, get_object_or_404, redirect
# 추가
form django.utils import timezone
...
...
# 추가
def answer_create(request, question_id):
"""
pybo 답변 등록
"""
question = get_object_or_404(Question, pk=question_id)
question.answer_set.create(content=request.POST.get('content'), create_date=timezone.now())
# 답변을 생성하기 위해 quesiton.answer_set.create 사용, question.answer_set은 질문의 답변을 의미
# Question과 Answer 모델은 서로 `ForeignKey`로 연결되어 있어 이처럼 사용 가능
# request.POST.get('content') 는 POST로 전송된 form 데이터 항목 중 content값을 의미한다.
return redirect('pybo:detail', question_id=question.id)
- 답변 등록시 텍스트창에 입력한 내용은
answer_create
함수의 첫번째 매개변수 request
를 통해 읽을 수 있다.2번째 방법
...
# 추가
from . models import Question, Answer
...
# 추가
def answer_create(request, question_id):
"""
pybo 답변등록
"""
question = get_object_or_404(Question, pk=questuon_id)
answer = Answer(question=question, content=request.POST.get('content'), create_date=timezone.now())
answer.save()
retunr redirect('pybo:detail', question_id=question.id)
- 1번째 방법과 2번째 방법 중 어떤 방식을 사용하더라도 결과는 동일하다.
- 답변을 생성한 후 질문 상세 화면을 다시 보여주기 위해 redirect 함수를 사용했다.
- redirect 함수는 페이지 이동을 위한 함수이다.
- detail 별칭은
question_id
가 필요하므로 question.id
를 인수로 전달했다.
답변 조회
- 등록된 답변을 상세 화면에 표시하려면 질문 상세 템플릿을 수정해야 한다.
- 경로 :
...templates\pybo\question_detail.html
...
<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>
...
question.answer_set.count
는 답변의 총 갯수를 의미한다.