일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 파이썬리스트컴프리헨션
- 리스트컴프리헨션
- 윈도우우분투듀얼부팅
- promise
- 인증인가
- decorator
- 파이썬
- 백준
- *args
- django
- CSS
- docker
- 자바스크립트
- JavaScript
- clone coding
- clone-coding
- wecode
- 자료구조
- 인터넷 네트워크
- RESTfulAPI
- **kwargs
- 파이썬문법
- QuerySet
- 알고리즘
- DP
- bcrypt
- 파이썬입출력
- 해시충돌
- 코딩테스트파이썬
- Python
- Today
- Total
개발기록장
[Django] 인스타그램 클론 코딩(5) - 좋아요(Like) 기능 구현 본문
[이전 글]
[Django] 인스타그램 클론 코딩(4) - 게시물과 댓글 C.R.U.D (+ RESTful API에서 Update에는 무슨 메소드를 써야하는가...)
[다음 글]
[Django] 인스타그램 클론 코딩(6) - 팔로우(follow) 기능 구현
인스타그램의 Like(좋아요) 기능은 users 테이블과 posts 테이블의 M:N 관계로 구현할 수 있다.
한 사람이 여러 게시물에 Like를 누를 수 있고, 하나의 게시물 입장에서 여러 사람에게 Like를 받을 수 있기 때문이다.
이 관계에서 posts가 기준이 되는 기능이므로 post/models.py의 Post class에 ManyToManyField를 추가해주었다.
1 - 1. user/models.py
from django.db import models
class User(models.Model):
email = models.EmailField(max_length=50, unique=True)
name = models.CharField(max_length=20, unique=True)
phone = models.CharField(max_length=15, unique=True)
password = models.CharField(max_length=300)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
1 - 2. post/models.py
from django.db import models
from user.models import User
class Post(models.Model):
user = models.ForeignKey('user.User', on_delete=models.CASCADE)
image_url = models.URLField(max_length=500)
content = models.TextField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
liked_users = models.ManyToManyField('user.User', through='Like', related_name='liked_posts')
class Meta:
db_table = 'posts'
(생략..)
class Like(models.Model):
user = models.ForeignKey('user.User', on_delete=models.CASCADE)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
-
위에서 설명한 대로 liked_users라는 attribute에 ManyToManyField를 이용하여 M:N 관계를 설정하였다.
-
liked_users라는 필드는 물리적으로 생기지 않는 필드이며 단지 두 테이블 사이에서 forward-many-to-many manager 역할을 한다.
** ManyToManyField에 대한 자세한 설명은 여기를 참고!!
-
이때 through 옵션을 지정하여 Like 라는 테이블을 중간 테이블로 사용하게 하였고,
-
User 입장에서 역참조를 쉽게 하기 위해 related_name도 'liked_posts'로 지정해주었다.
2. post/views.py
import json
from django.views import View
from django.http import JsonResponse
from .models import Post, Comment, Like
from user.models import User
from user.utils import login_decorator
(생략...)
class LikeView(View):
@login_decorator
def post(self, request):
data = json.loads(request.body)
user = request.user
post_id = data.get('post', None)
# KEY_ERROR check
if not post_id:
return JsonResponse({'message': 'KEY_ERROR'}, status=400)
# valid post check
if not Post.objects.filter(id=post_id).exists():
return JsonResponse({'message': 'INVALID_POST'}, status=400)
post = Post.objects.get(id=post_id)
if post.liked_users.filter(id=user.id).exists():
post.liked_users.remove(user)
message = 'Cancle'
else:
post.liked_users.add(user)
message = 'Like'
like_count = post.liked_users.count()
return JsonResponse({'message': message, 'like_count': like_count}, status=200)
-
request body에서 'Like' 대상인 post_id를 받아온다고 가정하고 코드를 짰다.
-
'Like'기능은 like라는 이름의 중간테이블에 'Like'를 누른 user_id와 그 대상인 post_id가 기록되는 형식으로 구현된다.
-
user가 이미 특정 게시물에 'Like'를 한 상태에서 또 한 번 'Like'를 누른다면 Like를 해제하는 것이므로 중간 테이블에서 해당 데이터를 삭제해주고, 아직 'Like'를 한 상태가 아니라면 데이터를 추가해준다.
-
중간 테이블(like)에 데이터를 추가하고 삭제하는 것은 forward_many_to_many_manager인 'post.liker_user.'를 이용하여 간결하게 구현할 수 있다.
3. post/usls.py
'Like' 기능 엔드포인트 추가
from django.urls import path
from .views import (
(생략..)
LikeView,
)
urlpatterns = [
(생략..)
path('/like', LikeView.as_view()),
]
'TIL > Django' 카테고리의 다른 글
[Django] 인스타그램 클론 코딩(7) - 대댓글 기능 구현 (0) | 2021.02.10 |
---|---|
[Django] 인스타그램 클론 코딩(6) - 팔로우(follow) 기능 구현 (0) | 2021.02.10 |
[Django] 인스타그램 클론 코딩(4) - 게시물과 댓글 C.R.U.D (RESTful API) (0) | 2021.02.09 |
[Django] 인스타그램 클론 코딩(3) - Authorization Decorator 만들고 활용하기 (1) | 2021.02.08 |
[Django] 인스타그램 클론 코딩(2) - 로그인 기능 구현 (0) | 2021.02.02 |