- Post 모델 개선 (author_id, updated_at, view_count 등) - Tag 모델 및 태그 기능 추가 - 댓글 기능 추가 - API 확장 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
154
blog/views.py
154
blog/views.py
@ -1,40 +1,53 @@
|
||||
# blog/views.py
|
||||
|
||||
from rest_framework import generics, permissions
|
||||
from rest_framework import generics, viewsets, permissions, status
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from .models import Post
|
||||
from .serializers import PostSerializer
|
||||
# from .utils import verify_token_with_auth_server
|
||||
import logging # 2025-04-29
|
||||
from rest_framework.response import Response
|
||||
from django.shortcuts import get_object_or_404
|
||||
from .models import Post, Comment, Tag
|
||||
from .serializers import PostSerializer, PostListSerializer, CommentSerializer, TagSerializer
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TagListView(generics.ListAPIView):
|
||||
"""태그 목록 조회"""
|
||||
queryset = Tag.objects.all()
|
||||
serializer_class = TagSerializer
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
logger = logging.getLogger(__name__) # 2025-04-29
|
||||
|
||||
class PostListView(generics.ListAPIView):
|
||||
queryset = Post.objects.all().order_by('-created_at')
|
||||
serializer_class = PostSerializer
|
||||
"""공개 포스트 목록 조회"""
|
||||
queryset = Post.objects.all()
|
||||
serializer_class = PostListSerializer
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = Post.objects.all()
|
||||
tag = self.request.query_params.get('tag')
|
||||
if tag:
|
||||
queryset = queryset.filter(tags__name=tag)
|
||||
return queryset
|
||||
|
||||
|
||||
class PostListCreateView(generics.ListCreateAPIView):
|
||||
queryset = Post.objects.all().order_by('-created_at')
|
||||
"""인증 사용자용 포스트 목록/생성"""
|
||||
queryset = Post.objects.all()
|
||||
serializer_class = PostSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def perform_create(self, serializer):
|
||||
# token = self.request.headers.get("Authorization", "").replace("Bearer ", "")
|
||||
# verify_token_with_auth_server(token)
|
||||
# verify_result = verify_token_with_auth_server(token)
|
||||
# 2025-04-14 로그 등록 (콘솔+FluentBit용)
|
||||
# if verify_result == None:
|
||||
# logger.info(f"Token verified")
|
||||
# else:
|
||||
# logger.info(f"Token error")
|
||||
|
||||
serializer.save(author_name=self.request.user.username)
|
||||
post_title=serializer.save(author_name=self.request.user.username)
|
||||
logger.info(f"Post titled '{post_title}' has been created.")
|
||||
user = self.request.user
|
||||
author_id = getattr(user, 'id', '') or getattr(user, 'email', '')
|
||||
author_name = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
instance = serializer.save(author_id=str(author_id), author_name=author_name)
|
||||
logger.info(f"Post titled '{instance.title}' has been created by {author_name}.")
|
||||
|
||||
|
||||
# ✅ 조회, 수정, 삭제 전부 처리
|
||||
class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""포스트 상세 조회/수정/삭제"""
|
||||
queryset = Post.objects.all()
|
||||
serializer_class = PostSerializer
|
||||
|
||||
@ -44,20 +57,97 @@ class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
|
||||
return [permissions.AllowAny()]
|
||||
|
||||
def perform_update(self, serializer):
|
||||
# token = self.request.headers.get("Authorization", "").replace("Bearer ", "")
|
||||
# verify_token_with_auth_server(token)
|
||||
instance = serializer.instance
|
||||
user = self.request.user
|
||||
user_id = str(getattr(user, 'id', '') or getattr(user, 'email', ''))
|
||||
username = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
|
||||
if serializer.instance.author_name != self.request.user.username:
|
||||
# 작성자 확인
|
||||
if instance.author_id != user_id and instance.author_name != username:
|
||||
raise PermissionDenied("작성자만 수정할 수 있습니다.")
|
||||
|
||||
serializer.save()
|
||||
post_title=serializer.save(author_name=self.request.user.username)
|
||||
logger.info(f"Post titled '{post_title}' has been updated.")
|
||||
logger.info(f"Post titled '{instance.title}' has been updated by {username}.")
|
||||
|
||||
def perform_destroy(self, instance):
|
||||
# token = self.request.headers.get("Authorization", "").replace("Bearer ", "")
|
||||
# verify_token_with_auth_server(token)
|
||||
user = self.request.user
|
||||
user_id = str(getattr(user, 'id', '') or getattr(user, 'email', ''))
|
||||
username = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
|
||||
if instance.author_name != self.request.user.username:
|
||||
# 작성자 확인
|
||||
if instance.author_id != user_id and instance.author_name != username:
|
||||
raise PermissionDenied("작성자만 삭제할 수 있습니다.")
|
||||
|
||||
title = instance.title
|
||||
instance.delete()
|
||||
logger.info(f"Post titled '{instance}' has been deleted.")
|
||||
logger.info(f"Post titled '{title}' has been deleted by {username}.")
|
||||
|
||||
|
||||
class CommentViewSet(viewsets.ModelViewSet):
|
||||
"""댓글/대댓글 CRUD ViewSet"""
|
||||
serializer_class = CommentSerializer
|
||||
|
||||
def get_permissions(self):
|
||||
if self.action in ['list', 'retrieve']:
|
||||
return [permissions.AllowAny()]
|
||||
return [permissions.IsAuthenticated()]
|
||||
|
||||
def get_post(self):
|
||||
"""현재 포스트 가져오기"""
|
||||
post_pk = self.kwargs.get('post_pk')
|
||||
return get_object_or_404(Post, pk=post_pk)
|
||||
|
||||
def get_queryset(self):
|
||||
post_pk = self.kwargs.get('post_pk')
|
||||
if post_pk:
|
||||
# list 액션에서만 최상위 댓글 반환, 나머지는 모든 댓글 접근 가능
|
||||
if self.action == 'list':
|
||||
return Comment.objects.filter(post_id=post_pk, parent__isnull=True)
|
||||
return Comment.objects.filter(post_id=post_pk)
|
||||
return Comment.objects.none()
|
||||
|
||||
def perform_create(self, serializer):
|
||||
post = self.get_post()
|
||||
user = self.request.user
|
||||
author_id = str(getattr(user, 'id', '') or getattr(user, 'email', ''))
|
||||
author_name = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
|
||||
# parent 검증 (대댓글인 경우)
|
||||
parent_id = self.request.data.get('parent')
|
||||
parent = None
|
||||
if parent_id:
|
||||
parent = get_object_or_404(Comment, pk=parent_id, post=post)
|
||||
|
||||
instance = serializer.save(
|
||||
post=post,
|
||||
parent=parent,
|
||||
author_id=author_id,
|
||||
author_name=author_name
|
||||
)
|
||||
logger.info(f"Comment created on post '{post.title}' by {author_name}.")
|
||||
|
||||
def perform_update(self, serializer):
|
||||
instance = serializer.instance
|
||||
user = self.request.user
|
||||
user_id = str(getattr(user, 'id', '') or getattr(user, 'email', ''))
|
||||
username = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
|
||||
# 작성자 확인
|
||||
if instance.author_id != user_id and instance.author_name != username:
|
||||
raise PermissionDenied("작성자만 수정할 수 있습니다.")
|
||||
|
||||
serializer.save()
|
||||
logger.info(f"Comment {instance.id} updated by {username}.")
|
||||
|
||||
def perform_destroy(self, instance):
|
||||
user = self.request.user
|
||||
user_id = str(getattr(user, 'id', '') or getattr(user, 'email', ''))
|
||||
username = getattr(user, 'username', '') or getattr(user, 'email', '')
|
||||
|
||||
# 작성자 확인
|
||||
if instance.author_id != user_id and instance.author_name != username:
|
||||
raise PermissionDenied("작성자만 삭제할 수 있습니다.")
|
||||
|
||||
comment_id = instance.id
|
||||
instance.delete()
|
||||
logger.info(f"Comment {comment_id} deleted by {username}.")
|
||||
Reference in New Issue
Block a user