좋아요의 데이터 모델과 뷰를 구현하기전에, 어떻게 구현하면 좋을지 꽤 오랜시간 고민한것 같다.
일단 그동안 내가 만들어왔던 데이터 모델과의 구조는 크게 다르지 않지만, 좋아요를 누른사람이 해당글에 한번더 좋아요를 누르면 좋아요가 사라지는 기능은 뷰에서 한번도 다룬 적이 없었다.
models.py (postings)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="likes")
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="likes")
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = "likes"
처음에는 boolen 데이터필드를 이용하여 좋아요를 누른사람은 데이터필드를 True로 해주고, 그렇지 않은 사람은 False로 처리하려 하였다. 하지만 그렇게 되면 오히려 쓸데없는 데이터만 더 늘어나는것 같고, 추후 처리하기가 더 까다로울 것 같아 그냥 user와 post를 포린키로 받아서 데이터가 존재하면 좋아요로 인식을 하게 데이터모델을 구현했다.
views.py (postings)
class LikeView(View):
@login_decorate
def post(self, request):
data = json.loads(request.body)
user = request.user
post = Post.objects.get(id = data["postID"])
if not Like.objects.filter(user = user, post = post).exists():
Like.objects.create(
user = user,
post = post,
)
return JsonResponse({"message" : "liked"}, status = 201)
Like.objects.filter(user = user, post = post).delete()
return JsonResponse({"message" : "unliked"}, status = 201)
LikeView의 구조를 설명하자면, 우선 @login_decorate 를 통해 headers 에서 전달받은 토큰의 아이디 값을 확인한다. 유저 인증을 완료하면 해당유저와 프론트에서 전달받은 해당포스트의 좋아요 여부를 filter를 통해 확인한다.
만약 해당 유저와 포스트가 일치하는 데이터가 없다면 좋아요 데이터를 생성해서 해당글에 좋아요를 추가한다. 만약 일치하는 데이터가 존재한다면 데이터를 삭제해준다.
@login_decorate
def get(self, request):
user = request.user
posts = Post.objects.filter(user = user)
my_posts = [{
"1. user_name" : user.name,
"2. content" : post.content,
"3. images" : [image.image_url for image in post.images.all()],
"4. likes" : len([like for like in post.likes.all()]),
"4. created_at": post.created_at
} for post in posts]
return JsonResponse({"my_posts" : my_posts}, status = 200)
이렇게 좋아요기능을 구현하면, 내가 작성한 포스트를 보여주는 뷰에서 완성된 좋아요기능을 바탕으로 게시물의 총좋아요 수를 함께 나타내줄 수 있다.