django 04. 장고 개인 프로젝트 3 - 자신의 글만 수정, 삭제 가능하도록 만들기

|

django 04. 장고 개인 프로젝트 (메모 앱) - 자신의 글만 수정, 삭제 가능하도록 만들기

인증에 따른 기능 제한을 추가하는 과정에서 고민한 부분과 배운 것을 기록합니다.

결과물


삭제, 수정 제한 - 내가 쓴 글만 수정, 삭제하기

  • 현재 상태 : 회원가입, 로그인, 로그아웃 기능을 추가했지만 누구나 글을 수정, 삭제할 수 있는 상태이다.
  • 원하는 상태 : 로그인한 사용자가 자신이 쓴 글만 수정, 삭제할 수 있도록 하고싶다.

어떻게 할 수 있을까? 1 (아이디어)

  • 삭제 버튼 숨김 / 표시
    • 로그인 전 : 모든 글에 수정, 삭제 버튼이 보이지 않는다.
    • 로그인 후 : 자신이 쓴 글에만 수정, 삭제 버튼이 보인다.
  • 수정, 삭제 시 사용자 확인
  • 수정, 삭제하려는 글의 글쓴이와, 로그인 되어있는 유저가 일치하는지 비교한다.

어떻게 할 수 있을까? 2 (구현방법)

삭제 버튼 숨김 / 표시

  • 로그인 전 : 모든 글에 수정, 삭제 버튼이 보이지 않는다.
    • .hidden 클래스의 추가/삭제 를 통해서 해당 태그 요소의 숨김/표시를 제어한다.
    • 수정, 삭제 버튼을 <span class="control hidden"> 태그로 둘러싸고 .hidden{display:none.}을 통해서 해당 요소를 숨김처리한다.
     <span class="control hidden"> <a href="{% url 'modify_memo' memokey=memo.pk %}"><img src="{% static 'image/edit.png' %}" class= "edit" alt="수정"></a> <a href="{% url 'delete_memo' memokey=memo.pk %}" onclick="return confirm('정말 삭제하시겠습니까?')"><img src="{% static 'image/delete.png' %}" class="delete" alt="삭제"></a> </span> 
  • 로그인 후 : 자신이 쓴 글에만 수정, 삭제 버튼이 보인다.
    • 로그인한 유저메모의 글쓴이를 비교하여 일치하는 경우만 수정, 삭제 버튼을 표시한다.(.hidden 클래스 삭제)
    • 로그인한 유저는 탬플릿 내에서 {user.username} 으로 표시할 수 있다.
    • 하지만, 자바스크립트에서는 {} 을 사용할 수 없다. 어쩌지?
    • {user.username}을 <span id="user_name"></span> 으로 둘러싸고 제이쿼리를 이용하여 해당 태그 안의 텍스트 값을 가져오자.
     // html <span id="user_name">{{ user.username }}</span>  // javascript $("#user_name").text() // user_name id를 가진 태그 안의 텍스트 값 가져오기 
    • 각 메모의 글쓴이는 탬플릿 내에서 for 문을 돌면서 {memo.name_id} 로 표시한다.
    • {memo.name_id}는 값이 여러개라서 ID를 쓸 수가 없네 어쩌지?
    • {memo.name_id}을 <span class="writer_name"></span> 으로 둘러싸고 제이쿼리를 이용하여 해당 태그 안의 텍스트를 리스트로 가져온다.
     // html <span class= "writer_name">{{memo.name_id}}</span>  // javascript $(".writer_name") // .writer_name 클래스를 가진 태그 전체를 리스트로 출력 $(".writer_name")[0].innerHTML // .innerHTML로 태그 안의 텍스트 값 가져오기 
    • for 문으로 반복을 돌면서, 로그인한 유저명 - user_name과 메모의 글쓴이 - writer_name이 일치한다면, 반복 순서 i에 해당하는 메모의 수정,삭제 버튼 블럭 태그를 선택하여 클래스값 hidden을 지워준다.
      • 수정,삭제 버튼 블럭 태그에 {forloop.counter} 를 통해서 특정 숫자를 포함한 아이디를 추가한다.
      • forloop.counter : 템플릿 내에서 for문으로 반복시 1씩 증가하는 숫자를 생성 가이드문서 (forloop.counter0 : 0부터 숫자를 생성)
     <!-- html --> <span class="control hidden" id = "control_id{{ forloop.counter0 }}"> <a href="{% url 'modify_memo' memokey=memo.pk %}"><img src="{% static 'image/edit.png' %}" class= "edit" alt="수정"></a> <a href="{% url 'delete_memo' memokey=memo.pk %}" onclick="return confirm('정말 삭제하시겠습니까?')"><img src="{% static 'image/delete.png' %}" class="delete" alt="삭제"></a> </span> 
    // javascript for(i = 0; i < $(".writer_name").length; i++){ if($("#user_name").text() == $(".writer_name")[i].innerHTML){ $("#control_id"+i).removeClass("hidden"); } } 

수정, 삭제 시 사용자 확인

  • 문제가 생겼다. 개발자 도구로 hidden 클래스를 지워주면 남의 글도 삭제, 수정할 수 있다. 어떻게 하지?
  • 수정, 삭제시 로그인 되어있는 유저와 해당 글의 글쓴이가 일치하는지 비교한다.
  • 삭제 : views.py 의 delete 메소드 수정
def delete(request, memokey): memo = Memos.objects.get(pk = memokey) if memo.name_id == User.objects.get(username = request.user.get_username()): memo.delete() return redirect('index') else: return render(request, 'memo_app/warning.html') 
  • 수정 : views.py 의 modify 메소드 수정
def modify(request, memokey): if request.method == "POST": #수정 저장 memo = Memos.objects.get(pk = memokey) form = PostForm(request.POST, instance=memo) if form.is_valid(): form.save() return redirect('index') else: #수정 입력 memo = Memos.objects.get(pk = memokey) if memo.name_id == User.objects.get(username = request.user.get_username()): memo = Memos.objects.get(pk = memokey) form = PostForm(instance = memo) return render(request, 'memo_app/modify.html', {'memo' : memo, 'form' : form}) else: return render(request, 'memo_app/warning.html')