작정하고 장고 38강 - Commentapp 마무리

IkSun·2023년 6월 27일

작정하고 장고

목록 보기
38/46

target_article 에 foreignkey 로 엮여 있는 comment 들을 모두 가져오기

<!-- /pragmatic/articleapp/templates/articleapp/detail.html -->
{% for comment in target_article.comment.all %}
	{% include 'commentapp/detail.html' with comment=comment %}
{% endfor %}

<!-- commentapp/detail.html 이 없기 때문에 만들어주기 -->
<div style="border: 1px solid; text-align: left; padding: 4%; margin: 1rem 0;
            border-radius: 1rem; border-color: #bbb;">
  <div>
    <strong>
      {{ comment.writer.profile.nickname }} <!-- 댓글의 작성자 : profile 의 nickname 에 접근 -->
    </strong>
    &nbsp&nbsp&nbsp
    {{ comment.created_at }}
  </div>
  <div style="margin: 1rem 0;">
    {{ comment.content }}
  </div>
</div>

Commentapp 의 DeleteView 만들기

# /pragmatic/commentapp/views.py 

...

class CommentDeleteView(DeleteView):
    model = Comment
    context_object_name = 'target_comment'
    template_name = 'commentapp/delete.html'

    def get_success_url(self):
        return reverse('articleapp:detail', kwargs={'pk': self.object.article.pk})
<!-- commentapp/detail.html 에 삭제 링크 만들어주기 -->
<div style="border: 1px solid; text-align: left; padding: 4%; margin: 1rem 0; border-radius: 1rem;
            border-color: #bbb;">
  <div>
    <strong>
      {{ comment.writer.profile.nickname }} <!-- 댓글의 작성자 : profile 의 nickname 에 접근 -->
    </strong>
    &nbsp&nbsp&nbsp
    {{ comment.created_at }}
  </div>
  <div style="margin: 1rem 0;">
    {{ comment.content }}
  </div>

  <!-- 게시글의 주인만 댓글 삭제가 가능하도록 설정 -->
  {% if comment.writer == user %}
  <!-- 삭제 링크 추가 -->
  <div style="text-align: right">
    <a href="{% url 'commentapp:delete'  pk=comment.pk %}" class="btn btn-danger rounded-pill">
      Delete
    </a>
  </div>
  {% endif %}
</div>
# /pragmatic/commentapp/urls.py 에 delete 경로 설정
from django.urls import path

from commentapp.views import CommentCreateView, CommentDeleteView

app_name = 'commentapp'

urlpatterns = [
    path('create/', CommentCreateView.as_view(), name='create'),
    path('delete/<int:pk>', CommentDeleteView.as_view(), name='delete'),
    # 어떤 comment 를 지울지 pk 로 받는다.
]
<!-- delete.html -->
{% extends 'base.html' %}

{% block content %}

  <div style="text-align : center; max-width: 500px; margin: 4rem auto;">
    <div class="mb-4"> <!-- margin bottom 해서 4배 -->
      <h4>Delete Comment : {{ target_comment.content }}</h4> <!-- 이 제목을 가진 게시글 삭제 -->
    </div>
    <form action="{% url 'commentapp:delete' pk=target_comment.pk %}" method="post">  <!--url 일원화, post 방식 으로 전송 -->
      {% csrf_token %}
      <input type="submit" class="btn btn-danger rounded-pill col-6 mt-3">
    </form>
  </div>

{% endblock %}

댓글 지우기

decorators.py 생성

  • comment 의 주인인지 아닌지 확인하는 과정
# /pragmatic/commentapp/decorators.py
from django.http import HttpResponseForbidden

from commentapp.models import Comment


def comment_ownership_required(func): # decorator 정의 (이 계정의 소유권이 필요하다는 이름)
    def decorated(request, *args, **kwargs): # request 를 받아
        # 우리가 원하는 작업 - 본인인지 확인하는 작업
        # get, post 등의 요청을 받으면서 pk 로 받은 값을 가지고 있는 User 객체가 user 가 되는 것
        comment = Comment.objects.get(pk=kwargs['pk'])
        # pk 를 확인해서 해당 pk 의 Comment 객체가 실제로 request 를 보낸 comment 과 같은지 아닌지 확인
        if not comment.writer == request.user: # 댓글의 저자가 지금 요청을 보내는 user 와 다르다면
            return HttpResponseForbidden()   # 금지 되었다고 내보내기
        return func(request, *args, **kwargs) # 같다면 그냥 보내주기
    return decorated
    # article_ownership_required 라는 decorator 를 만들었으니까 views.py 에 적용하기

views.py 에 decorator 추가

...
@method_decorator(comment_ownership_required, 'get')
@method_decorator(comment_ownership_required, 'post')
class CommentDeleteView(DeleteView):
    model = Comment
    context_object_name = 'target_comment'
    template_name = 'commentapp/delete.html'

    def get_success_url(self):
        return reverse('articleapp:detail', kwargs={'pk': self.object.article.pk})  # 해당 pk 를 가진 article 로 되돌아가라

이처럼 로그아웃을 하면 delete 버튼이 나오지 않게 된다.

commit

profile
공부한 것 기록용

0개의 댓글