Django | 인스타그램 클론 코딩(9) - 게시물 및 댓글 삭제, 수정

Sua·2021년 2월 13일
0

Django

목록 보기
15/23
post-thumbnail
post-custom-banner

💇‍♀️ 게시물 및 댓글 삭제, 수정

지난 시간에는 인스타그램 팔로우 기능을 구현하였습니다. 이번에는 게시물 및 댓글 삭제, 수정기능을 구현하겠습니다. 마찬가지로 로그인 데코레이터를 사용해서 로그인된 권한있는 유저만이 기능을 사용할 수 있도록 하겠습니다.

🔎 게시물 및 댓글 삭제, 수정 기능 분석

  1. 게시물과 해당 글을 작성한 유저만 삭제, 수정할 수 있습니다. 댓글도 마찬가지입니다.
  2. 게시물은 삭제와 수정 모두 가능하지만, 댓글은 삭제만 할 수 있고, 수정은 불가능합니다.
  3. 게시물을 수정할 때 게시물의 내용(content)만 바꿀 수 있고, 이미지(image_url)은 수정할 수 없습니다.

🛠 App

게시물 및 댓글 삭제, 수정 기능은 게시물과 관련되어 있으므로 posting 앱에서 작성합니다.

🖌 Model 작성

# posting/models.py

from django.db   import models
from user.models import User

class Posting(models.Model):
    content    = models.CharField(max_length=2000, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)   --> 추가
    user       = models.ForeignKey('user.User', on_delete=models.CASCADE)

    class Meta:
        db_table = 'postings'

Posting 클래스에 게시물의 생성시간을 기록하는 created_at만 있었는데, 수정시간을 기록하는 updated_at 필드를 추가하였습니다.

💣 View 작성

게시물 및 댓글 삭제

게시물과 댓글은 삭제를 하는 로직이 같으므로, 게시물을 기준으로 설명하도록 하겠습니다.

part1. PostingDetailView 만들기

게시물을 삭제한다면 보통 특정 게시물의 id를 받아 삭제합니다. 전체를 한꺼번에 삭제하지는 않죠. 따라서PostingDetailView 클래스를 만들어 상세 정보를 관리할 수 있도록 합니다.

class PostingDetailView(View):

part2. 로그인한 유저와 작성자가 같은지 확인

보통 게시물은 작성한 본인만 삭제할 수 있으므로, 로그인 토큰을 통해 받은 유저 정보(user)와 해당 포스팅의 작성자(posting.user)가 동일한지 확인합니다.

@login_decorator
def delete(self, request, posting_id):
    user = request.user

    if not Posting.objects.filter(id=posting_id).exists():
        return JsonResponse({'message':'POSTING_DOES_NOT_EXIST'}, status=404)

    posting = Posting.objects.get(id=posting_id)

    if user != posting.user:
        return JsonResponse({'message':'INVALID_USER'}, status=401)

게시물 수정

part1. PostingDetailView에 post 함수 사용

수정 또한 상세 정보를 다루는 것이므로 PostingDetailView에서 작성합니다.
수정할 때는 patchput을 사용해도 되지만 저는 post를 사용하도록 하겠습니다.

class PostingDetailView(View):
(...생략)

    @login_decorator
    def post(self, request, posting_id):

part2. 로그인한 유저와 작성자가 같은지 확인

삭제 기능과 마찬가지로 로그인한 유저와 작성자가 같은지 확인해야 합니다.

Part3. 게시물 수정하기

저는 수정 기능을 딕셔너리 get 메소드를 이용하여 구현합니다.
이 방식의 장점은 이 포스팅에 자세히 설명해두었습니다.

posting.content = data.get('content', posting.content)
posting.save()

👀 전체 View 코드

# posting/views.py

(...생략)

class PostingDetailView(View):
    @login_decorator
    def delete(self, request, posting_id):
        user = request.user

        if not Posting.objects.filter(id=posting_id).exists():
            return JsonResponse({'message':'POSTING_DOES_NOT_EXIST'}, status=404)

        posting = Posting.objects.get(id=posting_id)

        if user != posting.user:
            return JsonResponse({'message':'INVALID_USER'}, status=401)

        Posting.objects.filter(id=posting.id).delete()
        return JsonResponse({'message': 'SUCCESS'}, status=200)

    @login_decorator
    def post(self, request, posting_id):
        try:
            data = json.loads(request.body)
            user = request.user

            if not Posting.objects.filter(id=posting_id).exists():
                return JsonResponse({'message': 'POSTING_DOES_NOT_EXIST'}, status=404)

            posting = Posting.objects.get(id=posting_id)

            if user != posting.user:
                return JsonResponse({'message':'INVALID_USER'}, status=401)

            posting.content = data.get('content', posting.content)
            posting.save()
            return JsonResponse({'message': 'SUCCESS'}, status=201)

        except JSONDecodeError:
            return JsonResponse({'message':'JSON_DECODE_ERROR'}, status=400)
            
(...생략)

class CommentDetailView(View):
    @login_decorator
    def delete(self, request, comment_id):
        user = request.user

        if not Comment.objects.filter(id=comment_id).exists():
            return JsonResponse({'message':'COMMENT_DOES_NOT_EXIST'}, status=404)

        comment = Comment.objects.get(id=comment_id)

        if user != comment.user:
            return JsonResponse({'message':'INVALID_USER'}, status=401)

        Comment.objects.filter(id=comment.id).delete()
        return JsonResponse({'message': 'SUCCESS'}, status=200)

📬 url 경로 지정하기

# posting/urls.py

from django.urls import path
from .views import (
    PostingView,
    PostingSearchView,
    PostingDetailView,  --> 추가
    CommentView,
    CommentSearchView,
    CommentDetailView,  --> 추가
    LikeView, 
)

urlpatterns = [
    path('', PostingView.as_view()),
    path('/search/<int:user_id>', PostingSearchView.as_view()),
    path('/<int:posting_id>', PostingDetailView.as_view()),  --> 추가
    path('/comment', CommentView.as_view()),
    path('/comment/search/<int:posting_id>', CommentSearchView.as_view()),
    path('/comment/<int:comment_id>', CommentDetailView.as_view()),  --> 추가
    path('/like', LikeView.as_view()),
]
profile
Leave your comfort zone
post-custom-banner

0개의 댓글