import 부분이나 대부분의 부분은 생략되었고 일부분만 올렸다.
like, follow, comment에 관련한 것만 올렸다. login_decorator는 전글을 참고하면 좋을 것 같다!
from django.db import models
class User(models.Model):
email = models.EmailField(max_length=200, unique=True, verbose_name='Username')
password = models.CharField(max_length=300, verbose_name='Password')
nickname = models.CharField(max_length=50)
phone = models.CharField(null=True, max_length=15)
registered_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
class UserFollow(models.Model):
follower = models.ForeignKey('User', related_name='follower', on_delete=models.CASCADE)
following = models.ForeignKey('User', related_name='following', on_delete=models.CASCADE)
class Meta:
db_table = 'user_follow'
- UserFollow 라는 클래스를 따로 만들어 follow를 하는 사람을 follower, follow 당하는 사람을 following이라고 저장하였다.
- related_name 을 쓴 이유는 같은 클래스 UserFollow 에서 User를 두번 참조하기 때문인데, related_name을 쓰지 않으면 에러가 난다.
...
class FollowView(View):
@login_decorator
def post(self, request):
try:
data = json.loads(request.body)
follower = request.user
follower_id = follower.id
following_id = data['following_id']
if UserFollow.objects.filter(follower_id=follower_id, following_id=following_id).exists():
UserFollow.objects.get(follower_id=follower_id, following_id=following_id).delete()
return JsonResponse({'message': 'SUCCESS'}, status=200)
UserFollow.objects.create(follower_id=follower_id, following_id=following_id)
return JsonResponse({'message': 'SUCCESS'}, status=200)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
- 요청을 보내는 데이터에는 팔로우를 하는 사람의 정보 (그 전에 login을 하니까 토큰으로), 그 사람이 팔로우를 할 사람의 정보(following_id)를 담는다.
- 이미 팔로우 한 사람을 다시 팔로우 하는 경우에는 언팔로우 하는 경우로 인식하여 delete를 진행한다.
- 팔로우하지 않은 상태라면 팔로우를 한다.
... import, class Post 생략...
class Comment(models.Model):
text = models.CharField(max_length=200)
posted_time = models.DateTimeField(auto_now_add=True)
updated_time = models.DateTimeField(auto_now=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
user = models.ForeignKey('user.User', on_delete=models.CASCADE)
parent = models.ForeignKey('self', null=True, blank=True, related_name='replies', on_delete=models.CASCADE)
class Meta:
db_table = 'comments'
class Like(models.Model):
user = models.ForeignKey('user.User', on_delete=models.CASCADE)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
liked_time = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'likes'
class Comment
- comment에 parent 이라는 attribute는 상위 댓글인지 아닌지 확인해준다. True이면 상위 댓글, False면 답글로 인식하도록 했다.
- parent attribute는 Self를 써서 자기 자신을 참조할 수 있도록 했다. related_name 은 replies 이다.
class Like
- like 클래스는 user와 게시글(post)을 참조하도록 했다.
...
class CommentsView(View):
@login_decorator
def post(self, request):
try:
data = json.loads(request.body)
user = request.user
text = data['text']
post_id = data['post_id']
parent_id = data.get('parent_id', None)
if User.objects.filter(email=user.email).exists():
Comment.objects.create(
text = text,
post = Post.objects.get(id=post_id),
parent_id = parent_id,
user = user
)
return JsonResponse({'message':'SUCCESS'},status=200)
return JsonResponse({'message':'INVALID_USER'},status=401)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
- request할 정보에는 comment의 내용, 댓글을 달 게시글의 아이디를 담았다. login을 해야하기 때문에 로그인한 유저의 토큰도 담는다.
- parent_id 도 담았는데, 특정 댓글에 대한 답글이라면 부모 댓글을 요청에 보내고, 만약 자기자신이 부모 답글이라면 요청에 담아서 보내지 않는다.
- 유저의 정보가 존재한다면 답글을 만들어준다.
- 같은 comment는 작성할 수 있기 때문에 굳이 같은 내용의 댓글을 걸러준다던지 하는 기능은 만들지 않았다.
class LikeView(View):
@login_decorator
def post(self, request):
try:
data = json.loads(request.body)
user = request.user
post = Post.objects.get(id=data['post_id'])
if Like.objects.filter(post=post, user=user).exists():
Like.objects.get(post=post, user=user).delete()
like_counts = Like.objects.filter(post=post).count()
return JsonResponse({'message':'SUCCESS', 'like_counts':like_counts},status=200)
like = Like.objects.create(post=post, user=user)
like_counts = Like.objects.filter(post=post).count()
return JsonResponse({'message':'SUCCESS', 'like_counts':like_counts},status=200)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
- request할 정보에는 login을 해야하기 때문에 로그인한 유저의 토큰과 좋아할 게시글의 아이디를 담는다.
- like를 이미 했을 경우에는 좋아요를 없애는 것으로 간주한다.
- like_counts를 이용해 해당 게시글의 좋아요 수를 계산한다.
- like가 없는 경우에는 좋아요를 하는 것으로 간주했다.