[수정 일시]
먼저 질문 및 답변이 수정된 날짜를 확인할수있는 modify_date 속성을 추가하자.
projects\mysite\pybo\models.py 를 수정하자.
null=True 는 데이터베이스에서 modify_date 칼럼에서 null을 허용한다는 의미이며, blank=True 는 form.is_valid()를 통한 입력 데이터 검증시 값이 없어도 된다는 의미이다. 즉, 아직 modify_date 값이 없다 = 아직 수정을 하지 않았을 경우 값을 비워둘 수 있다는것을 의미한다. 모델이 변경되었으므로 makemigrations, migrate 명령을 수행하자.
[질문 수정]
먼저 질문 수정 버튼을 만들어주자.
projects\mysite\templates\pybo\question_detail.html 를 수정하자.
해석하면 수정 버튼은 로그인한 사용자와 글쓴이가 동일한 경우에만 노출되도록 {% if request.user == question.author %} 을 적용했다. 그 아래는 버튼을 구성한 것이다. 그리고 {% url 'pybo:question_modify' question.id %} URL이 추가되었으므로 pybo/urls.py 에 URL 매핑규칙을 추가해야한다.
projects\mysite\pybo\urls.py 를 수정하자.
보면 알겠지만 views.question_modify 함수를 참조한다고 적어놨다. 아직 우리는 저 함수가 없기 때문에 새로 만들어주자,
projects\mysite\pybo\views.py 에 추가하자.
question_modify 함수는 로그인한 사용자(request.user)와 수정하려는 질문의 글쓴이(question.author)가 다르면 '수정권한이 없습니다' 오류를 발생한다. 이 오류를 발생시키기 위해 messages 모듈을 이용했다. messages 는 장고가 제공하는 모듈로 넌필드 오류를 발생시킬때 사용한다.
'수정' 버튼을 클릭하면 http://localhost:8000/pybo/question/modify/2/ 페이지가 GET 방식으로 호출되어 질문수정 화면이 보여진다. 질문 수정화면에서 사용한 템플릿은 질문 등록시 사용했던 pybo/question_form.html 파일과 동일하다. 질문 수정화면에서 저장하기 버튼을 클릭하면 http://localhost:8000/pybo/question/modify/2/ 페이지가 POST 방식으로 호출되어 데이터가 수정된다. form 태그에 action 속성이 없는 경우 디폴트 action 은 현재 페이지가 되기 때문이다.
GET 요청인 경우 질문수정 화면에 조회된 질문의 제목과 내용이반영될 수 있도록 form = QuestionForm(instance=question) 을 추가했다. 폼 생성시 이처럼 instance 값을 지정하면 폼의 속성 값이 instance 값으로 채워진다. 따라서 질문을 수정하는 화면에서 제목과 내용이 채워진 채로 보일 것이다.
POST 요청인 경우 수정된 내용을 반영해야 하는 케이스 이므로 form = QuestionForm(request.POST, instance=question) 을 추가해주었다. 이 코드의 의미는 instance 를 기준으로 QuestionForm 을 생성하지만 request.POST 의 값으로 덮어쓰라는 의미이다. 따라서 질문 수정화면에서 제목 또는 내용을 변경하여 POST 로 요청하면 변경된 내용이 QuestionForm 에 저장된다.
질문 수정일시는 question.modify_date = timezone.now() 로 현재일시를 저장한다.
길게 적혀있어 어렵지만 내가 이해한 바로 설명해보자면, 질문 수정버튼을 누르면 GET 방식으로 된다는 것을 의미하고. GET 방식으로 요청된 경우에는 질문수정 화면이 나오는데 이 때 양식은 질문생성할때의 question_form.html 과 동일하고, 안의 내용들은 수정하려던 질문의 제목 과 내용이 자동으로 채워져있다. 이 상태에서 내용이나 제목을 수정해 수정하기 버튼을 누르는 것은 POST 방식으로 요청한다는 것같다. POST 방식으로 요청한 경우 수정한 내용들로 원래 있던 내용과 제목에 덮어쓰라는 것을 의미한다. 그리고 수정했기 때문에 값이 비어있던 수정일시도 현재시간으로 추가해 저장한다. 이러한 의미인것같다.
messages 모듈에 의해 발생되는 '수정권한이 없습니다' 오류가 표시될 수 있도록 질문 상세 화면 위쪽에 오류 영역을 추가해야한다.
projects\mysite\templates\pybo\question_detail.html 을 수정하자.
수정은 로그인 한 사용자와 글 작성자가 동일한 경우에만 가능하기 때문에 오류는 표시되지 않지만. 비 정상적인 방법으로 질문을 수정할 경우에 이 오류를 보여주어야 한다.
테스트해보자.
로그인 사용자와 작성자가 같을경우 수정 버튼이 보이고, 아닐경우 보이지 않는다. 수정 버튼을 눌렀을 경우에도 잘 작동되는지 확인해보자. 잘 작동되지만 아직은 수정일시가 표시되지는 않는다.
[질문 삭제]
질문삭제 버튼을 추가하기위해
projects\mysite\templates\pybo\question_detail.html 을 수정하자.
삭제버튼은 수정버튼과 달리 href 속성 값을 javascript:void(0) 으로 설정했다. href 속성값을 이렇게 설정하면 해당 링크를 클릭해도 아무런 동작도 하지 않는다. 그리고 삭제를 실행할 URL을 얻기 위해 data-url 속성을 추가하고, 삭제 버튼이 눌리는 이벤트를 확인할 수 있도록 class 속성에 'delete' 항목을 추가했다. data-uri 속성은 자바스크립트에서 클릭 이벤트 발생시 this.dataset.uri와 같이 사용하여 그 값을 얻을 수 있다. href 에 삭제 URL을 직접 사용하지 않고 이러한 방식을 사용하는 이유는 삭제 버튼을 클릭했을때 '정말 삭제 하시겠습니까?' 같은확인창이 필요하기 때문이다.
삭제 버튼을 눌렀을 때 확인창을 나오게 하기 위해서는 다음과 같은 자바스크립트가 필요하다. 일단 눈으로만 보며 뜻을 알아보자.
<script type = 'text/javascript'>
const delete_elements = document.getElementsByClassName("delete");
Array.form(delete_elements).forEach(function(element)
{
element.addEventListener('click', function() {
if(confirm("정말로 삭제하시겠습니까?")){
location.href = this.dataset.uri;
};
});
});
</script>
이 자바스크립트의 의미는 delete 라는 클래스를 포함하는 컴포넌트(버튼이나 링크) 를 클릭하면 "정말로 삭제하시겠습니까?" 라는 질문을 하고 "확인" 버튼을 선택했을때 해당 컴포넌트의 data-uri 값으로 URL 호출을 하라는 의미이다. "확인" 대신 "취소"를 선택하며 아무런 일도 발생하지 않는다. 이와 같은 스크립트를 추가하면 "삭제" 버튼을 클릭하고 "확인" 버튼을 선택하면 data-uri 속성에 해당하는 {% url 'pybo:question_delete' question.id %} 이 호출된다.
자바스크립트는 HTML 구조에서 </body> 태그 바로 위에 삽입하는 것을 추천한다. 왜냐하면 이렇게 해야 화면 렌더링이 완료된 후에 자바스크립트가 실행되기 때문이다. 화면 렌더링이 완료되지 않은 상태에서 자바스크립트를 실행하면 화면의 값을 읽지 못하는 오류가 발생할수도 있고 화면 로딩이 지연되는 문제가 발생할 수 도 있다.
projects\mysite\templates\base.html 을 다음과 같이 수정하자.
base.html 을 상속하는 템플릿들에서 content 블록을 구성했던것 처럼 script 를 구현한다.</body> 태그 바로 위에 {% block script %}, {% endblock %} 블록을 추가했다. 이렇게하면 base.html 을 상속하는 템플릿은 자바스크림트의 삽입위치를 신경쓸 필요없이 저 블록을 사용해 자바스크립트를 작성하면 된다.
이를 이용해
projects\mysite\templates\pybo\question_detail.html 을 다음과 같이 수정하자.
그리고 data-uri 에 {% url 'pybo:question_delete' question.id %} URL이 추가되었으므로 pybo/urls.py 에 매핑규칙을 추가해야한다.
proejcts\mysite\pybo\urls.py 를 수정하자.
그리고 위에서 정의한 views.question_delete 함수도 작성해야한다.
projects\mysite\pybo\views.py 를 다음과 같이 수정하자.
로그인이 필요하므로 @login_required 에너테이션을 적용한다. 로그인한 사용자와 글쓴이가 같을 경우에만 삭제할수 있다.
테스트 해보자
잘 작동하는지도 테스트해보자.
'Django > 따라하는 장고' 카테고리의 다른 글
24. views.py 분리 (0) | 2022.11.21 |
---|---|
23. 답변 수정 및 삭제 (0) | 2022.11.19 |
21. author 표시 (0) | 2022.11.17 |
20. author 속성 (0) | 2022.11.16 |
19. 회원가입 (0) | 2022.11.10 |