Byeonguk Kim

안녕하세요. 29살의 조금은 늦은 나이로 새롭게 개발자로 시작하는 신입 개발자입니다. 포트폴리오 [https://deaguowl.github.io]

Django 23. 장고 댓글 삭제 및 수정 구현하기

16 May 2019 » Django

2019.05.16 장고 댓글 삭제 및 수정 구현하기

댓글 수정 및 삭제 구현하기

  1. views.py 만들기
  2. 템플릿 만들기
  3. urls.py 만들기

update , delete 페이지에 접근했을 때 구동되는 로직들

함수형 뷰 구현하기


def comment_update(request, comment_id):

    comment = get_object_or_404(Comment, pk=comment_id)
    document = get_object_or_404(Document, pk=comment.document.id)

    if request.user != comment.author:
        messages.warning(request, "권한 없음")
        return redirect(document)

    if request.method == "POST":
        form = CommentForm(request.POST, instance=comment)
        if form.is_valid():
            form.save()
            return redirect(document)
    else:
        form = CommentForm(instance=comment)
    return render(request,'board/comment/comment_update.html',{'form':form})


def comment_delete(request, comment_id):

    comment = get_object_or_404(Comment, pk=comment_id)
    document = get_object_or_404(Document, pk=comment.document.id)

    if request.user != comment.author and not request.user.is_staff and request.user != document.author:
        messages.warning(request, '권한 없음')
        return redirect(document)

    if request.method == "POST":
        comment.delete()
        return redirect(document)
    else:
        return render(request, 'board/comment/comment_delete.html', {'object':comment})

  1. 해당 객체가 있는지 확인 : get_object_or_404, objects.get , objects.filter.exists
  2. 객체에 대한 권한 체크 - 작성자, 관리자
  3. get : 해당 페이지에 필요한 값 입력 받기
  4. post : 입력 받은 값에 대한 처리 -> 삭제 , 업데이트
  5. 처리 후 페이지 이동
  6. 여기서 중요한 것은 instance = comment를 넣어주어서 기존에 등록되었던 값이 보이도록 해줘야 한다.
  7. instance를 등록해주지 않으면 새로운 값으로 생각하고 새롭게 생성하게 된다.

클래스 뷰


from django.views.generic.edit import CreateView, UpdateView, DeleteView

class CommentUpdate(UpdateView):
    model = Comment
    fields = [ 'text']
    template_name_suffix = '_update'
    # success_url = '/'


    def dispatch(self, request, *args, **kwargs):
        object = self.get_object()
        if object.author != request.user:
            messages.warning(request, '수정할 권한이 없습니다.')
            return HttpResponseRedirect('/')
            # 삭제 페이지에서 권한이 없다! 라고 띄우거나
            # detail페이지로 들어가서 삭제에 실패했습니다. 라고 띄우거나
        else:
            return super(CommentUpdate, self).dispatch(request, *args, **kwargs)

from django.http import HttpResponseRedirect
from django.contrib import messages


class CommentDelete(DeleteView):
    model = Comment
    template_name_suffix = '_delete' 
    success_url = '/'

    def dispatch(self, request, *args, **kwargs):
        object = self.get_object()
        if object.author != request.user:
            messages.warning(request, '삭제할 권한이 없습니다.')
            return HttpResponseRedirect('/')
        else:
            return super(CommentDelete, self).dispatch(request, *args, **kwargs)
  1. 객체에 대한 권한 체크 - 작성자, 관리자 - dispatch
  2. 해당 객체가 있는지 확인 : get_object, get_queryset
  3. get : 해당 페이지에 필요한 값 입력 받기 - def get
  4. post : 입력 받은 값에 대한 처리 -> 삭제 , 업데이트 - def post
  5. dispatch를 통해 get과 post를 한번에 처리할 수 있고 class generic 뷰를 상속받아서 더 간단하게 구현 가능하다.
  6. 처리 후 페이지 이동

def dispatch에서 POST와 GET나누어서 처리하기

def dispatch(self, request, *args, **kwargs):
    object = self.get_object()
    if request.method == "POST":
        super().post(request, *args, **kwargs)
    else:   
        super().post(request, *args, **kwargs)

템플릿 만들기

delet.html (board/comment/comment_delete.html)


{ % extends 'base.html' % }
{ % block content % }
<!--진짜 지울건지 확인을 받아야 한다. form  보여줄 필요가 없다.-->
<div class="alert alert-primary" role="alert">
  진짜로  지우실 건가요?
</div>
<form action="" method ="post">
    { % csrf_token% }
    <input type="submit" value="Delete OK">
</form>
{ % endblock % }

  • form에 따로 받을 양식은 없다. post 형태로 오면 그냥 지우면 된다.

update.html (board/comment/comment_update.html)


{ % extends 'base.html' % }


{ % block content % }

<form action="" method = "post" enctype="multipart/form-data">
    { % csrf_token % }
    <table>
    
        </table>
    <input type="submit" value="Write">

</form>

{ % endblock % }

  • update를 할 때 중요한 것은 바로 전체 자료가 남아 있도록 해야 한다.
 if request.method == "POST":
        form = CommentForm(request.POST, instance=comment)
        if form.is_valid():
            form.save()
            return redirect(document)
    else:
        form = CommentForm(instance=comment)
  • 여기서 알 수 있듯이 함수형 뷰로 해당 로직을 처리해줄 때는 꼭 instance= comment를 남겨서 기존에 데이터를 넘어오도록 해야 한다.

urls.py 연결하기 (함수형 뷰에서 구현했다고 가정)


from .views import comment_delete, comment_update

app_name = 'board'

urlpatterns = [
    path('comment/delete/<int:comment_id>/', comment_delete, name="comment_delete"),
    path('comment/update/<int:comment_id>/', comment_update, name="comment_update"),
 
]

잘 되는지 확인해보기

  • 해당 내용에 대해 잘 작동하는지 확인해본다.