본문 바로가기

Django/따라하는 장고

10. 답변 등록하기

[답변 등록 폼]

 

질문 상세 템플릿에 답변을 저장할 수 있는 form을 추가해보자.

pybo/question_detail.html 을 다음과 같이 수정하자.

답변의 내용을 입력할 수 있는 textarea 와 답변을 저장 할 수있는 "답변등록" 버튼도 추가했다. 답변 저장을 위한 URL은 form 태그의 action 속성에 {% url 'pybo:answer_create' question.id %} 로 지정했다. form 태그 바로 밑에 있는 {% csrf_token %} 은 보안에 관련된 항목으로 form으로 전송한 데이터가 실제 웹페이지에서 작성한 데이터인지를 판단하는 역할을 한다. 막약 해커가 이상한 방법으로 데이터를 전송할 경우에는 서버에서 발행한 csrf_torkn 값과 해커가 일방적으로 보낸 csrf_token 값이 일치하지 않기 때문에 블로킹 된다. 그럴므로 항상 form 태그 바로 밑에 {% cstf_token %} 태그를 위치 시켜야한다.

 

[URL 매핑]

 

이제 질문 상세 템플릿을 위와 같이 고친 후 질문 상세 페이지를 요청하면

answer_create 별칭을 찾을수 없다는 의미의 오류를 만나게 된다. 그 이유는 질문 상세 템플릿에 {% url 'pybo:answer_create' question.id %} 처럼 pybo:answer_create 별칭을 사용했기 때문이다. 이 오류를 해결하기 위해서는 pybo/urls.py 을 다음과 같이 URL 매핑을 등록해야 한다.

answer_create 별칭에 해당하는 URL 매핑 규칙을 등록했다. 이제 http://localhost:8000/pybo/answer/create/2/ 와 같은 페이지를 요청하면 URL 매핑 규칙에 의해 views.answer_create 함수가 호출된다. 그렇다면 views.answer_create 함수를 만들어줘야 한다. pybo/views.py 파일을 다음과 같이 수정하자.

answer_create 함수의 매개변수 question_id는 URL 매핑에 의해 그 값이 전달된다. 만약 http://localhost:8000/pybo/answer/create/2/ 라는 페이지를 요청하면 매개변수 question_id 에는 2 라는 값이 전달된다.

그리고 답변 등록시 텍스트창에 입력한 내용은 answer_create 함수의 첫번째 매개변수인 request 객체를 통해 읽을 수 있다. 즉, request.POST.get('content') 로 텍스트창에 입력한 내용을 읽을 수 있다는 뜻이다. request.POST.get('content') 는 POST로 전송된 form 데이터 항목 중 content 값을 의미한다. 그리고 답변을 생성하기 위해 question.answer_set.create를 사용했다. question.answer_set 은 질문의 답변을 의미한다. Question 과 Answer 모델은 서로 ForeignKey 로 연결되어 있기 때문에 이처럼 사용할 수 있다. 

 

답변을 저장하는 또 다른 방법은 다음처럼 Answer 모델을 직접 사용하는 방법이다.

필요없는 부분은 주석처리 했다

원래 적었던 부분은 주석처리 했다. 답변을 생성한 후 질문 상세 화면을 다시 보여주기 위해 redirect 함수를 사용했다. redirect 함수는 페이지 이동을 위한 함수이다. pybo:detail 별칭에 해당하는 페이지로 이동하기 위해 redirect 함수를 사용했다. pybo:detail 별칭에 해당하는 URL은 question_id 가 필요하므로 question.id 를 인수로 전달했다.

 

[답변 저장]

 

이제 질문 상세 화면을 호출해 보자.

텍스트 창에 아무 값이나 입력하고 답변을 등록하자. 그런데 등록해도 화면에 아무런 변화가 없다. 그 이유는 아직 등록된 답변을 표시하는 기능을 템플릿에 추가하지 않았기 때문이다.

 

[답변 조회]

 

등록된 답변을 질문 상세 화면에 표시하려면 pybo/question_detail.html 을 다음과 같이 수정하자.

 중간 부분에 질문에 등록된 답변을 확일할 수 있는 영역을 추가했다. question.answer_set.count 는 답변의 총 갯수를 뜻한다.

이제 다시 질문 상세 화면을 호출하면

실수로 비슷한 답변을 2개 달아서 2개가 나온다

이제 답변을 저장하고 확인까지 할수있게 되었다!

'Django > 따라하는 장고' 카테고리의 다른 글

12. 부트스트랩  (0) 2022.10.27
11. 스태틱 디렉토리  (0) 2022.10.25
9. URL 별칭  (0) 2022.10.20
8. 템플릿  (1) 2022.10.19
7. 장고 관리자  (1) 2022.10.17