drf ๋ฐฑ์๋๊ฐ๋ฐ + ํ๋ก ํธ๊ฐ๋ฐ
: ์ด๋ฒ ํ๋ก์ ํธ๋ ํํ๋ก์ ํธ๋ก ์์ํฉ๋๋ค.
serializers.py
from rest_framework import serializers
from article.models import (
Article as ArticleModel,
Comment as CommentModel,
CommentLikeBridge,
ArticleVoteBridge,
)
from user.models import User as User
from user.serializers import UserSerializer
class CommentSerializer(serializers.ModelSerializer):
comments_related_article = serializers.SerializerMethodField()
author = serializers.SerializerMethodField()
count = serializers.SerializerMethodField()
nickname = serializers.SerializerMethodField()
def get_comments_related_article(self,obj):
return obj.article.id
def get_author(self,obj):
return obj.comment_author.username
def get_nickname(self,obj):
return obj.comment_author.nickname
def get_count(self,obj):
like_count = CommentLikeBridge.objects.filter(comment_id=obj.id).count()
return like_count
# custum update
def update(self, instance, validated_data):
for key, value in validated_data.items():
if key == "comment_author":
instance.user(value)
continue
setattr(instance, key, value)
instance.save()
return instance
class Meta :
model = CommentModel
fields = ['id', 'article', 'author','nickname', 'comment_created_at', 'comment_contents', 'comments_related_article', 'count']
class ArticleSerializer(serializers.ModelSerializer):
comment_set = CommentSerializer(many=True)
author = serializers.SerializerMethodField()
vote = serializers.SerializerMethodField()
nickname = serializers.SerializerMethodField()
board = serializers.SerializerMethodField()
def get_board(self,obj):
return obj.board.name
def get_author(self,obj):
return obj.article_author.username
def get_nickname(self,obj):
return obj.article_author.nickname
def get_vote(self,obj):
votes = ArticleVoteBridge.objects.filter(article_id=obj.id)
votes = list(votes.values())
vote_count = dict(fox=0, green=0, miss=0)
for vote in votes:
if vote['category'] == 'ํญ์ค์
๋๋ค':
vote_count['fox'] += 1
elif vote['category'] == '๊ทธ๋ฆฐ๋ผ์ดํธ':
vote_count['green'] += 1
else:
vote_count['miss'] += 1
vote_count['count'] = vote_count['fox'] + vote_count['green'] + vote_count['miss']
return vote_count
# custum update
def update(self, instance, validated_data):
for key, value in validated_data.items():
if key == "article_author":
instance.set_author(value)
continue
setattr(instance, key, value)
instance.save()
return instance
class Meta:
model = ArticleModel
fields = ['id','author','nickname','article_title','article_image', 'board', 'vote',
'article_contents','article_post_date',
'article_exposure_date','comment_set',
]
views.py
from unicodedata import category
from django.core.paginator import Paginator
from rest_framework.pagination import LimitOffsetPagination
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions
from urllib import parse
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import permission_classes
from rest_framework_simplejwt.authentication import JWTAuthentication
from article.models import (
Article as ArticleModel,
Comment as CommentModel,
Board as BoardModel,
ArticleLike,
CommentLike,
CommentLikeBridge,
ArticleLikeBridge,
ArticleVoteBridge,
Vote as VoteModel
)
from article.serializers import (
ArticleSerializer,
CommentSerializer,
)
# ๊ฒ์ํ ๋ณ ๊ฒ์๊ธ ํ์ด์ง๋ค์ด์
class ArticlePagination(APIView, LimitOffsetPagination):
def get(self, request, format=None):
board = request.query_params.getlist('board')[0]
page = int(request.query_params.getlist('page')[0])
# if board == 'HOT':
# articles = ArticleModel.objects.filter(board__name=board)
# print(articles)
articles = ArticleModel.objects.filter(board__name=board).order_by("-id")[((page-1)*10):(page*10)]
if board == 'HOT':
all = list(ArticleModel.objects.all().values())
articles_id = []
for article in all:
articles_id.append(article['id'])
vote_counts = []
for id in articles_id:
vote_count = ArticleVoteBridge.objects.filter(article_id=id).count()
if vote_count >= 1:
num = 0
num = num + 1
vote_counts.append(vote_count)
print(num)
count_list = {name:value for name, value in zip(articles_id, vote_counts)}
vote_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:num]
ranking = []
for i in range(num):
ranking.append(vote_rank[i][0])
article_rank = ArticleModel.objects.filter(id__in = ranking)
results = self.paginate_queryset(article_rank, request, view=self)
serializer = ArticleSerializer(results, many=True)
return self.get_paginated_response(serializer.data)
else:
results = self.paginate_queryset(articles, request, view=self)
serializer = ArticleSerializer(results, many=True)
return self.get_paginated_response(serializer.data)
# ํฌํ์ ํ3 ๋ฆฌ์คํ
class MostVotedArticleView(APIView):
def get(self, request):
articles = list(ArticleModel.objects.all().values())
articles_id = []
for article in articles:
articles_id.append(article['id'])
vote_counts = []
for id in articles_id:
vote_count = ArticleVoteBridge.objects.filter(article_id=id).count()
vote_counts.append(vote_count)
count_list = { name:value for name, value in zip(articles_id, vote_counts)}
vote_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:3]
first = vote_rank[0][0]
second = vote_rank[1][0]
third = vote_rank[2][0]
ranking = [first, second, third]
article_rank = ArticleModel.objects.filter(id__in = ranking)
return Response(ArticleSerializer(article_rank, many=True).data)
# ๋๊ธ ํ์ด์ง๋ค์ด์
๋ฆฌ์คํ
class CommentPagination(APIView, LimitOffsetPagination):
def get(self, request, format=None):
comments = CommentModel.objects.all()
results = self.paginate_queryset(comments, request, view=self)
serializer = CommentSerializer(results, many=True)
return self.get_paginated_response(serializer.data)
class ArticleView(APIView):
permission_classes = [permissions.AllowAny]
# ๋ชจ๋ ๊ฒ์๊ธ ๋ฆฌ์คํ
def get(self, request):
articles = list(ArticleModel.objects.all().order_by("-id"))
result = ArticleSerializer(articles, many=True).data
return Response(result)
# ๊ฒ์๊ธ ์์ฑ
def post(self, request):
if request.user.is_anonymous:
return Response({"error":"๊ธ ์์ฑ์ ์ํด ๋ก๊ทธ์ธ์ ํด์ฃผ์ธ์."})
else:
try:
board = BoardModel.objects.get(name=request.data.get('board'))
article = ArticleModel.objects.create(
article_author = request.user,
article_title = request.data.get('article_title',''),
article_contents = request.data.get('article_contents',''),
article_image = request.FILES['article_image'],
article_exposure_date = request.data.get('article_exposure_date',''),
board = board,
)
except:
board = BoardModel.objects.get(name=request.data.get('board'))
article = ArticleModel.objects.create(
article_author = request.user,
article_title = request.data.get('article_title',''),
article_contents = request.data.get('article_contents',''),
article_exposure_date = request.data.get('article_exposure_date',''),
board = board,
)
if len(request.data.get('article_title','')) <= 1 :
return Response({"error":"title์ด 1์ ์ดํ๋ผ๋ฉด ๊ฒ์๊ธ์ ์์ฑํ ์ ์์ต๋๋ค."})
elif len(request.data.get('article_contents','')) <= 10 :
return Response({"error":"contents๊ฐ 10์ ์ดํ๋ผ๋ฉด ๊ฒ์๊ธ์ ์์ฑํ ์ ์์ต๋๋ค."})
else:
article.save()
return Response({"message":"๊ฒ์๋ฌผ ์์ฑ ์๋ฃ!!"})
# ๊ฒ์๋ฌผ ์
๋ฐ์ดํธ
def put(self, request, obj_id):
article = ArticleModel.objects.get(id=obj_id)
if request.user == article.article_author or request.user.is_admin:
article_serializer = ArticleSerializer(article, data=request.data, partial=True, context={"request": request})
if article_serializer.is_valid():
article_serializer.save()
return Response(article_serializer.data, status=status.HTTP_200_OK)
else:
return Response(article_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response({"message":"๊ฒ์๊ธ ์์ ์ ๊ฒ์๊ธ ์์ฑ์๋ง ํ ์ ์์ต๋๋ค."})
# ๊ฒ์๋ฌผ ์ญ์
def delete(self, request, obj_id):
article = ArticleModel.objects.get(id=obj_id)
title = article.article_title
user = article.article_author
if request.user == article.article_author or request.user.is_admin:
ArticleModel.objects.get(id=obj_id).delete()
return Response({'message': f'{user}๋์ {title} ๊ฒ์๊ธ์ด ์ญ์ ๋์์ต๋๋ค.'})
else:
return Response({"message":"๊ฒ์๊ธ ์ญ์ ๋ ๊ฒ์๊ธ ์์ฑ์๋ง ํ ์ ์์ต๋๋ค."})
# article detail ํ์ด์ง article/<obj_id>/detail/
class ArticleDetailView(APIView):
def get(self, request, obj_id):
article = ArticleModel.objects.get(id=obj_id)
return Response(ArticleSerializer(article).data)
class CommentView(APIView):
def get(self, request, obj_id):
return Response(CommentSerializer(obj_id).data)
# ๋๊ธ ์์ฑ
def post(self, request, obj_id):
if request.user.is_anonymous:
return Response({"error":"๋๊ธ ์์ฑ์ ์ํด ๋ก๊ทธ์ธ์ ํด์ฃผ์ธ์."})
else:
user = request.user
request.data['article'] = ArticleModel.objects.get(id=obj_id)
contents = request.data.get('comment_contents','')
comment = CommentModel(
article = request.data['article'],
comment_author = user,
comment_contents = contents,
)
comment.save()
return Response({"message":"๋๊ธ ์์ฑ ์๋ฃ!"})
# ๋๊ธ ์
๋ฐ์ดํธ
def put(self, request, obj_id):
data = request.data
comment = CommentModel.objects.get(id=obj_id)
if request.user == comment.comment_author or request.user.is_admin:
comment_serializer = CommentSerializer(comment, data, partial=True, context={"request": request})
if comment_serializer.is_valid():
comment_serializer.save()
return Response(comment_serializer.data, status=status.HTTP_200_OK)
else:
return Response({"error":"๋๊ธ ์์ ์ ๋๊ธ ์์ฑ์๋ง ๊ฐ๋ฅํฉ๋๋ค."})
# ๋๊ธ ์ญ์
def delete(self, request, obj_id):
comment = CommentModel.objects.get(id=obj_id)
comment_author = comment.comment_author
article_author = comment.article.article_author
if request.user == comment.comment_author or request.user.is_admin or request.user == article_author:
CommentModel.objects.get(id=obj_id).delete()
return Response({'message': f'{comment_author}๋์ ๋๊ธ์ด ์ญ์ ๋์์ต๋๋ค.'})
else:
return Response({'error': '๋๊ธ ์ญ์ ๊ถํ์ด ์์ต๋๋ค'})
# ๊ฒ์๊ธ ๊ณต๊ฐ
class ArticleLikeView(APIView):
authentication_classes = [JWTAuthentication]
def post(self, request, article_id):
like = ArticleLike.objects.create()
article_title = ArticleModel.objects.get(id=article_id)
all = list(ArticleLikeBridge.objects.all().values())
print(all)
all_id = []
for obj in all:
all_id.append(obj['user_id'])
if request.user.id in all_id:
article_like = ArticleLikeBridge.objects.get(user_id=request.user.id)
article_like.delete()
return Response({'message': f'{request.user}๋๊ป์ {article_title.article_title}์ ๊ณต๊ฐ์ ์ทจ์ํ์
จ์ต๋๋ค.'})
else:
article_like = ArticleLikeBridge(
article_id = article_id,
user_id = request.user.id,
like_id = like.id,
category = request.data.get('category')
)
article_like.save()
return Response({'message': f'{request.user}๋๊ป์ {article_title.article_title}์ {article_like.category}ํ์
จ์ต๋๋ค.'})
# ๊ฒ์๊ธ ํฌํ
class ArticleVoteBridgeView(APIView):
authentication_classes = [JWTAuthentication]
# ๊ฒ์๊ธ ํฌํ ์นด์ดํธ
def get(self, request, article_id):
votes = ArticleVoteBridge.objects.filter(article_id=article_id)
votes = list(votes.values())
count = dict(fox=0, green=0, miss=0)
for vote in votes:
if vote['category'] == 'ํญ์ค์
๋๋ค':
count['fox'] += 1
elif vote['category'] == '๊ทธ๋ฆฐ๋ผ์ดํธ':
count['green'] += 1
else:
count['miss'] += 1
return Response(count)
def post(self, request, article_id):
vote = VoteModel.objects.create()
article_title = ArticleModel.objects.get(id=article_id)
all = list(ArticleVoteBridge.objects.all().values())
article_vote = ArticleVoteBridge.objects.filter(user_id=request.user.id)
vote_article = article_vote.filter(article_id=article_id)
vote_article.delete()
all_id = []
for obj in all:
all_id.append(obj['user_id'])
try:
article_vote = ArticleVoteBridge.objects.filter(user_id=request.user.id)
if article_vote.category != request.data.get('category'):
article_vote.delete()
new_vote = ArticleVoteBridge(
article_id = article_id,
user_id = request.user.id,
vote_id = vote.id,
category = request.data.get('category',"")
)
new_vote.save()
return Response({'message': f'{new_vote.category}๋ก ์ฌํฌํ!'})
elif article_vote.category == request.data.get('category'):
return Response({'message': '์ด๋ฏธ ํฌํํ์
จ์ต๋๋ค.'})
else:
article_vote = ArticleVoteBridge(
article_id = article_id,
user_id = request.user.id,
vote_id = vote.id,
category = request.data.get('category',"")
)
article_vote.save()
return Response({'message': f'{article_vote.category}์ ํํ!'})
except:
article_vote = ArticleVoteBridge(
article_id = article_id,
user_id = request.user.id,
vote_id = vote.id,
category = request.data.get('category',"")
)
article_vote.save()
return Response({'message': f'{article_vote.category}์ ํํ!'})
# ๋๊ธ ๊ณต๊ฐ
class CommentLikeView(APIView):
authentication_classes = [JWTAuthentication]
# ๋๊ธ ๊ณต๊ฐ ์นด์ดํธ
def get(self, request, comment_id):
like_count = CommentLikeBridge.objects.filter(comment_id=comment_id).count()
return Response(like_count)
def post(self, request, comment_id):
like = CommentLike.objects.create()
comment = CommentModel.objects.get(id=comment_id)
contents = comment.comment_contents
all = list(CommentLikeBridge.objects.all().values())
all_id = []
for obj in all:
all_id.append(obj['user_id'])
if request.user.id in all_id:
# for i in all:
# id = i['comment_id']
try:
CommentLikeBridge.objects.get(comment_id=comment_id)
comment_like = CommentLikeBridge.objects.get(comment_id=comment_id)
if comment_like.user_id == request.user.id:
comment_like.delete()
return Response({'message': f'{request.user}๋๊ป์ {contents[0:10]}...๋๊ธ์ ๊ณต๊ฐ์ ์ทจ์ํ์
จ์ต๋๋ค.'})
except:
comment_like = CommentLikeBridge(
comment_id = comment_id,
user_id = request.user.id,
like_id = like.id,
category = request.data.get('category')
)
comment_like.save()
return Response({'message': f'{request.user}๋๊ป์ {contents[0:10]}...๋๊ธ์ {comment_like.category}ํ์
จ์ต๋๋ค.'})
else:
comment_like = CommentLikeBridge(
comment_id = comment_id,
user_id = request.user.id,
like_id = like.id,
category = request.data.get('category')
)
comment_like.save()
return Response({'message': f'{request.user}๋๊ป์ {contents[0:10]}...๋๊ธ์ {comment_like.category}ํ์
จ์ต๋๋ค.'})
# ๊ณต๊ฐ์ ๊ฒ์๊ธ ํ3 ๋ฆฌ์คํ
class MostLikedArticleView(APIView):
def get(self, request):
articles = list(ArticleModel.objects.all().values())
articles_id = []
for article in articles:
articles_id.append(article['id'])
like_counts = []
for id in articles_id:
like_count = ArticleLikeBridge.objects.filter(article_id=id).count()
like_counts.append(like_count)
count_list = { name:value for name, value in zip(articles_id, like_counts)}
like_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:3]
ranking = []
for rank in range(len(like_rank)):
if like_rank[rank][0] is not None:
ranking.append(like_rank[rank][0])
else:
pass
article_rank = ArticleModel.objects.filter(id__in = ranking)
return Response(ArticleSerializer(article_rank, many=True).data)
# ๊ณต๊ฐ์ ๋๊ธ ํ3 ๋ฆฌ์คํ
class MostLikedCommentView(APIView):
def get(self, request):
comments = list(CommentModel.objects.all().values())
comments_id = []
for comment in comments:
comments_id.append(comment['id'])
like_counts = []
for id in comments_id:
like_count = CommentLikeBridge.objects.filter(comment_id=id).count()
like_counts.append(like_count)
count_list = { name:value for name, value in zip(comments_id, like_counts)}
like_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:3]
first = like_rank[0][0]
second = like_rank[1][0]
third = like_rank[2][0]
forth = like_rank[3][0]
fifth = like_rank[4][0]
sixth = like_rank[5][0]
ranking = [first, second, third, forth, fifth, sixth]
comment_rank = CommentModel.objects.filter(id__in = ranking)
return Response(CommentSerializer(comment_rank, many=True).data)
# ํฌํ์ ํ3 ๋ฆฌ์คํ
class MostVotedArticleView(APIView):
def get(self, request):
articles = list(ArticleModel.objects.all().values())
articles_id = []
for article in articles:
articles_id.append(article['id'])
vote_counts = []
for id in articles_id:
vote_count = ArticleVoteBridge.objects.filter(article_id=id).count()
vote_counts.append(vote_count)
count_list = { name:value for name, value in zip(articles_id, vote_counts)}
vote_rank = sorted(count_list.items(), key=lambda x: x[1], reverse=True)[:3]
first = vote_rank[0][0]
second = vote_rank[1][0]
third = vote_rank[2][0]
ranking = [first, second, third]
article_rank = ArticleModel.objects.filter(id__in = ranking)
return Response(ArticleSerializer(article_rank, many=True).data)
class SearchResult(APIView):
permission_classes = [permissions.AllowAny]
# ๊ฒ์ ๊ฒฐ๊ณผ ๋ฆฌ์คํ
def post(self, request):
keywords = request.data.get('search')
type= request.data.get('type')
# ๋ด์ฉ ๊ฒ์
if type == '๋ด์ฉ':
searched_contents = ArticleModel.objects.filter(article_contents__contains=keywords)
result = ArticleSerializer(searched_contents, many=True).data
return Response(result)
# ์์ฑ์ ๊ฒ์
elif type == '์์ฑ์':
searched_authors = ArticleModel.objects.filter(article_author__username=keywords)
result = ArticleSerializer(searched_authors, many=True).data
return Response(result)
# ์ ๋ชฉ + ๋ด์ฉ ๊ฒ์
elif type == '์ ๋ชฉ+๋ด์ฉ':
searched_contents = ArticleModel.objects.filter(article_contents__contains=keywords)
searched_titles = ArticleModel.objects.filter(article_title__contains=keywords)
searched = searched_contents.union(searched_titles)
result = ArticleSerializer(searched, many=True).data
return Response(result)
# ์ ๋ชฉ ๊ฒ์
else:
searched_titles = ArticleModel.objects.filter(article_title__contains=keywords)
result = ArticleSerializer(searched_titles, many=True).data
return Response(result)
# ๋ฉ์ธํ์ด์ง ๊ฒ์ํ๋ณ ์ํฐํด ๋ฆฌ์คํ
class ArticleByBoard(APIView):
def get(self, request):
boards = request.query_params.getlist('boards', '')
results = []
for board in boards:
articles = ArticleModel.objects.filter(board__name=board).order_by("-id")[:5]
result = ArticleSerializer(articles, many=True).data
results_data = {
f"{board}" : result
}
results.append(results_data)
return Response(results)