Django | 인스타그램 클론 코딩(7) - 게시물 좋아요

Sua·2021년 2월 11일
1

Django

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

👩‍❤️‍👨 게시물 좋아요

지난 시간에는 인스타그램 댓글 등록, 표출 기능을 구현하였습니다. 이번에는 게시물 '좋아요' 기능을 구현하도록 하겠습니다. 마찬가지로 로그인 데코레이터를 사용해서 로그인된 권한있는 유저만이 '좋아요'를 누를 수 있도록 해보겠습니다.

🔎 좋아요 기능 분석

  1. 한 명의 유저는 하나의 게시물에 대해 하나의 좋아요만 할 수 있습니다.
  2. 이미 누른 좋아요 버튼을 다시 누르면 좋아요가 해제됩니다.
  3. 좋아요를 누르면 해당 포스팅의 좋아요 개수가 변합니다.

🛠 App

좋아요 기능은 게시물과 관련되어 있으므로 posting 앱에서 작성하겠습니다.

🖌 Model 작성

# posting/models.py

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

(..생략)

class Like(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey('user.User', on_delete=models.CASCADE)
    posting = models.ForeignKey('Posting', on_delete=models.CASCADE)

    class Meta:
        db_table = 'likes'

💣 View 작성

part1. 이미 좋아요를 누른 게시물일 때는 좋아요 해제

해당 유저가 해당 게시물에 이미 좋아요를 눌렀는지 filter()exists()로 확인합니다.
만약 매칭되는 데이터가 있다면 delete()로 삭제합니다.

if Like.objects.filter(user=user, posting=posting).exists():
    Like.objects.filter(user=user, posting=posting).delete()

part2. 좋아요 갯수 보여주기

인스타그램 페이지에서는 좋아요 버튼과 함께 좋아요 갯수를 함께 보여줍니다.
해당 포스팅의 좋아요 갯수를 count()로 계산하여 JsonResponse로 응답할 때 함께 보내줍니다.

like_count = Like.objects.filter(posting=posting).count()
return JsonResponse({'message': 'SUCCESS', 'like_count':like_count}, status=200)

👀 좋아요 전체 View 코드

# posting/views.py

import json
from json.decoder import JSONDecodeError

from django.http  import JsonResponse
from django.views import View

from posting.models import Posting, Image, Comment, Like  --> 수정
from user.models    import User
from user.utils     import login_decorator

(..생략)

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

            posting_id = data.get('posting_id', None)

            if not posting_id:
                return JsonResponse({'message':'KEY_ERROR'}, status=400)

            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 Like.objects.filter(user=user, posting=posting).exists():
                Like.objects.filter(user=user, posting=posting).delete()
                like_count = Like.objects.filter(posting=posting).count()
                return JsonResponse({'message': 'SUCCESS', 'like_count':like_count}, status=200)

            Like.objects.create(
                user    = user,
                posting = posting
            )
            like_count = Like.objects.filter(posting=posting).count()
            return JsonResponse({'message': 'SUCCESS', 'like_count': like_count}, status=200)

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

📬 url 경로 지정하기

# posting/urls.py

from django.urls import path
from .views import (
    (..생략)
    LikeView, 
)

urlpatterns = [
    (..생략)
    path('/like', LikeView.as_view()),
]
profile
Leave your comfort zone
post-custom-banner

0개의 댓글