[django] 점프 투 장고 - 장고 심화 9

Joy·2020년 6월 27일
0

Django | 점프투장고

목록 보기
17/22

수정과 삭제

작성한 질문과 답변을 수정하고 삭제할 수 있는 기능을 추가

수정일시 추가

언제 수정되었는지 확인할 수 있도록 :

  • Question과 Answer 모델에 수정일시(modify_date) 속성을 추가
  • makemigrations + migrate 실행




질문 수정

상세조회 화면에 질문을 수정할 수 있는 버튼을 추가

질문수정 버튼

quesiton_detail.html

  • 로그인한 사용자와 글쓴이가 동일한 경우에만 노출되도록 {% if request.user == question.author %}
 {% if request.user == question.author %}
        <div class="my-3">
            <a href="{% url 'pybo:question_modify' question.id  %}" 
               class="btn btn-sm btn-outline-secondary">수정</a>
        </div>
        {% endif %}

질문수정 URL

위에 url 추가되었으니까 매핑 추가

[pybo\urls.py]

path('question/modify/<int:question_id>/', views.question_modify, name='question_modify'),

질문수정 함수

위 매핑에 의해 실행되는 views.question_modify 함수 작성

[pybo/views.py]

@login_required(login_url='common:login')
def question_modify(request, question_id):
    """
    pybo 질문수정
    """
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, '수정권한이 없습니다')
        return redirect('pybo:detail', question_id=question.id)

    if request.method == "POST":
        form = QuestionForm(request.POST, instance=question)
        if form.is_valid():
            question = form.save(commit=False)
            question.author = request.user
            question.modify_date = timezone.now()  # 수정일시 저장
            question.save()
            return redirect('pybo:detail', question_id=question.id)
    else:
        form = QuestionForm(instance=question)
    context = {'form': form}
    return render(request, 'pybo/question_form.html', context)
  • 로그인한 사용자request.user와 수정하려는 질문의 글쓴이(question.author)가 다를 경우에는 "수정권한이 없습니다"라는 오류를 발생
  • 오류 발생은 messages 모듈을 이용

messages: 장고가 제공하는 함수. 넌필드 오류(non-field error)를 발생시킬 경우에 사용

  • "수정"버튼 클릭 시 /pybo/question/modify/2/ 페이지가 GET 방식으로 호출 -> 질문 수정화면 호출

form = QuestionForm(instance=question) 는 화면에 기존 제목/내용이 보이게
폼 생성시 이처럼 instance값을 지정하면 폼에 값이 채워지게 됨

  • "저장" 버튼 클릭 시 pybo/question/modify/2/ 페이지가POST 방식으로 호출 -> 데이터 수정
    form = QuestionForm(request.POST, instance=question) : 조회된 질문의 내용으로 QuestionForm을 생성하지만 request.POST의 값으로 덮어쓰라는 의미. 질문 수정화면에서 제목 또는 내용을 변경하여 POST로 호출하면 변경된 내용이 QuestionForm에 저장될

테스트




질문삭제

질문삭제 버튼추가

[quesiton_detail.html]

<a href="#" class="delete btn btn-sm btn-outline-secondary"
       data-uri="{% url 'pybo:question_delete' question.id  %}">삭제</a>
  • href의 링크를 "#"으로 하고 data-uri 라는 속성을 추가

data-uri 속성은 jQuery에서 $(this).data('uri') 와 같이 사용하여 그 값을 얻을 수 있다.

  • class속성에 "delete"라는 항목을 추가

jQuery

삭제시 확인창 -> 자바스크립트 코드 필요 (Qjuery로 작성)

<script type='text/javascript'>
$(document).ready(function(){
    $(".delete").on('click', function() {
        if(confirm("정말로 삭제하시겠습니까?")) {
            location.href = $(this).data('uri');
        }
    });
});
</script>
  • $(document).ready(function()는 화면이 로드된후 자동으로 호출되는 jQuery 함수
  • "삭제" - "확인" 시 data-uri 속성에 해당하는 {% url 'pybo:question_delete' question.id %} URL이 호출

스크립트 블록

이 자바스크립트는 jQuery로 작성되었기 때문에 jQuery 라이브러리가 먼저 로드된 후 호출되어야 함. jQuery 라이브러리는 부트스트랩의 기능을 사용하기 위해 이미 base.html에 포함되어 있음

탬플릿에서 사용하기해 [base.html] 수정

{% block script %}
{% endblock %}
  • block 추가하기 -> base 상속받는 템플릿은 이 블록에 jQ 스크립트 작성 가능

[question_detail.html] 수정

  • block script 코드를 넣고 그 안에 질문 삭제 jQ 코드 쓰기

질문삭제 URL

data-uri에 {% url 'pybo:question_delete' question.id %} URL이 추가되었으므로 pybo/urls.py에 URL 매핑을 추가

[pybo/urls.py]

 path('question/delete/<int:question_id>/', views.question_delete, name='question_delete'),

질문삭제 함수

매핑에 실행되는 함수 뷰에 추가

[pybo\views.py]

@login_required(login_url='common:login')
def question_delete(request, question_id):
    """
    pybo 질문삭제
    """
    question = get_object_or_404(Question, pk=question_id)
    if request.user != question.author:
        messages.error(request, '삭제권한이 없습니다')
        return redirect('pybo:detail', question_id=question.id)
    question.delete()
    return redirect('pybo:index')




답변수정

답변글을 수정하고 삭제할 수 있도록 기능을 추가

답변을 수정할때는 답변등록을 하는 템플릿이 따로 없기 때문에 답변 수정을 위한 템플릿을 추가로 작성

답변수정 버튼

[pybo\question_detail.html]

버튼 추가

답변수정 URL

url 매핑

답변수정 함수

뷰에 함수추가

답변수정 폼

답변을 수정하기 위한 템플릿(answer_form.html)은 별도로 작성




답변삭제

답변삭제 버튼

답변삭제 URL

답변삭제 함수




수정일시 표시

상세조회 화면에서 수정일시를 확인할 수 있도록 템플릿을 수정

{% if question.modify_date %}
<div class="badge badge-light p-2 text-left mx-3">
  <div class="mb-2">modified at</div>
  <div>{{ question.modify_date }}</div>
</div>
{% endif %}

 {% if answer.modify_date %}
 <div class="badge badge-light p-2 text-left mx-3">
     <div class="mb-2">modified at</div>
     <div>{{ answer.modify_date }}</div>
 </div>
{% endif %}
profile
roundy

0개의 댓글