Skip to content

Commit

Permalink
Merge pull request #24 from Django-Wanted-Internship-3-Team/feature/i…
Browse files Browse the repository at this point in the history
…ssue-010

게시물 상세 API 작성
  • Loading branch information
simseulnyang authored Oct 30, 2023
2 parents a3af62f + ba89c3a commit 13a0b91
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 1 deletion.
3 changes: 3 additions & 0 deletions posts/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
class PostsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "posts"

def ready(self):
import posts.signals # noqa
20 changes: 20 additions & 0 deletions posts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,23 @@ class PostQuerySerializer(serializers.Serializer):
help_text="created_at, updated_at, view_count, like_count, share_count를 기준으로 오름차순/내림차순으로 정렬하여 조회합니다. (default: created_at)",
)
hashtag = serializers.CharField(required=False, help_text="조회할 해시태그입니다. (default: 본인계정)")


class PostDetailSerializer(serializers.ModelSerializer):
hashtag = HashTagSerializer(many=True, read_only=True)

class Meta:
model = Post
fields = [
"content_id",
"post_type",
"title",
"content",
"view_count",
"like_count",
"share_count",
"created_at",
"updated_at",
"hashtag",
"user",
]
10 changes: 10 additions & 0 deletions posts/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.db.models.signals import pre_save
from django.dispatch import receiver

from posts.models import Post


@receiver(pre_save, sender=Post)
def increment_view_count(sender, instance, **kwargs):
# 게시글을 조회할 때 조회수 증가
instance.view_count += 1
84 changes: 84 additions & 0 deletions posts/tests/views/test_posts_detail_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import uuid

from django.contrib.auth import get_user_model
from django.db import transaction
from django.urls import reverse
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APITestCase

from posts.models import HashTag, Post

User = get_user_model()


class PostDetailViewTest(APITestCase):
@classmethod
def setUpTestData(cls):
# 테스트 사용자 생성
cls.user = User.objects.create_user(username="testuser1", password="testpass1", email="test1@email.com")

# 테스트 해시태그 생성
cls.hashtag = HashTag.objects.create(name="hashtag1")

# 테스트 게시물 생성 및 content_id 저장
cls.content_ids = []

# 테스트 게시물 생성
for i in range(1, 6):
post = Post.objects.create(
content_id=uuid.uuid4(),
user=cls.user,
post_type="facebook",
title=f"test title {i}",
content=f"test content {i}",
view_count=10 * i,
like_count=5 * i,
share_count=2 * i,
created_at=timezone.now(),
updated_at=timezone.now(),
)
post.hashtag.set([cls.hashtag])
cls.content_ids.append(str(post.content_id))

def setUp(self):
pass

def test_get_existing_post_content_id(self):
response = self.client.get(
path=reverse("post-detail", kwargs={"content_id": self.content_ids[0]}),
data={"type": "all", "hashtag": self.hashtag.id, "ordering": "created_at", "search": ""},
)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_get_not_existing_post_content_id(self):
non_existing_content_id = "00000000-0000-0000-0000-000000000001"
response = self.client.get(
path=reverse("post-detail", kwargs={"content_id": non_existing_content_id}),
data={"type": "all", "hashtag": self.hashtag.id, "ordering": "created_at", "search": ""},
)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_increment_view_count(self):
content_id = self.content_ids[0]

# 현재 조회수 가져오기
# 초기값 - 1 (조회와 동시에 count가 됨)
post = Post.objects.get(content_id=content_id)
initial_view_count = post.view_count - 1

# 게시물 조회
with transaction.atomic():
response = self.client.get(
path=reverse("post-detail", kwargs={"content_id": content_id}),
data={"type": "all", "hashtag": self.hashtag.id, "ordering": "created_at", "search": ""},
)

# 조회수 업데이트 확인
post.refresh_from_db()
updated_view_count = post.view_count

print("initial_view_count", initial_view_count)

self.assertEqual(updated_view_count, initial_view_count + 1)
self.assertEqual(response.status_code, status.HTTP_200_OK)
3 changes: 2 additions & 1 deletion posts/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.urls import path

from posts.views import PostListView, StatisticsListView
from posts.views import PostDetailView, PostListView, StatisticsListView

urlpatterns = [
path("statistics/", StatisticsListView.as_view(), name="statistics"),
path("", PostListView.as_view(), name="list"),
path("<str:content_id>/", PostDetailView.as_view(), name="post-detail"),
]
19 changes: 19 additions & 0 deletions posts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.db.models import Count, Q, Sum
from django.db.models.functions import TruncDay, TruncHour
from django.db.models.query import QuerySet
from django.shortcuts import get_object_or_404
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.pagination import LimitOffsetPagination
Expand All @@ -18,6 +19,7 @@
from posts.models import Post
from posts.paginations import PaginationHandlerMixin
from posts.serializers import (
PostDetailSerializer,
PostListSerializer,
PostQuerySerializer,
StatisticsListSerializer,
Expand Down Expand Up @@ -210,3 +212,20 @@ def get_ordering(self, posts: QuerySet[Post], ordering: str) -> QuerySet[Post]:
return posts.order_by(ordering)
else:
raise InvalidParameterException(f"ordering 값 {ordering}를 잘못 선택하셨습니다.")


class PostDetailView(APIView):
# @TODO: IsAuthenticated로 변경 @simseulnyang
permission_classes = [AllowAny]

@swagger_auto_schema(
operation_summary="content_id에 해당하는 게시글 상세 조회",
responses={
status.HTTP_200_OK: PostDetailSerializer,
},
)
def get(self, request: Request, content_id: str) -> Response:
post = get_object_or_404(Post, content_id=content_id)
serializer = PostDetailSerializer(post)

return Response(serializer.data, status=status.HTTP_200_OK)

0 comments on commit 13a0b91

Please sign in to comment.