diff --git a/backend/account/views.py b/backend/account/views.py index 5fc1595..08a265a 100644 --- a/backend/account/views.py +++ b/backend/account/views.py @@ -157,9 +157,7 @@ def post(self, request, *args, **kwargs): # Delete the verification token once the user has been registered successfully. token.delete() - return Response( - {"detail": "User registration complete."}, status=status.HTTP_200_OK - ) + return Response({"detail": "User registration complete."}, status=status.HTTP_200_OK) class EmailUpdateView(APIView): @@ -180,6 +178,7 @@ class EmailUpdateView(APIView): responses={ 200: "Successful Response", 400: "Bad Request", + 401: "Unauthorized Request", }, ) def post(self, request, *args, **kwargs): @@ -246,9 +245,7 @@ def post(self, request, *args, **kwargs): # Delete the verification token once the user has changed their email successfully. token.delete() - return Response( - {"detail": "Email updated successfully."}, status=status.HTTP_200_OK - ) + return Response({"detail": "Email updated successfully."}, status=status.HTTP_200_OK) class ResetPasswordView(APIView): @@ -267,6 +264,7 @@ class ResetPasswordView(APIView): 200: "Successful Response", 400: "Bad Request", 401: "Unauthorized Request", + 404: "User Not Found", }, ) def post(self, request, *args, **kwargs): @@ -339,9 +337,7 @@ def post(self, request, *args, **kwargs): # Delete the verification token once the user has reset their password successfully. token.delete() - return Response( - {"detail": "Password reset successfully."}, status=status.HTTP_200_OK - ) + return Response({"detail": "Password reset successfully."}, status=status.HTTP_200_OK) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @@ -363,8 +359,9 @@ class UserProfileView(APIView): ), ], responses={ - 200: "Successful Response", + 200: UserProfilePublicSerializer, 400: "Bad Request", + 404: "User Not Found", }, ) def get(self, request, username, *args, **kwargs): @@ -396,8 +393,10 @@ def get(self, request, username, *args, **kwargs): ), ], responses={ - 200: "Successful Response", + 200: UserProfilePrivateSerializer, 400: "Bad Request", + 401: "Unauthorized Request", + 404: "User Not Found", }, ) def put(self, request, username, *args, **kwargs): @@ -424,9 +423,10 @@ class AccountView(APIView): ), ], responses={ - 200: "Successful Response", + 200: AccountSerializer, 400: "Bad Request", 401: "Unauthorized Request", + 404: "User Not Found", }, ) def get(self, request, username, *args, **kwargs): @@ -452,6 +452,7 @@ def get(self, request, username, *args, **kwargs): 200: "Successful Response", 400: "Bad Request", 401: "Unauthorized Request", + 404: "User Not Found", }, ) def delete(self, request, username, *args, **kwargs): diff --git a/backend/backend/urls.py b/backend/backend/urls.py index 6ba4f1c..1f0778c 100644 --- a/backend/backend/urls.py +++ b/backend/backend/urls.py @@ -22,9 +22,9 @@ schema_view = get_schema_view( openapi.Info( - title="Blog Post API", + title="Blog API", default_version="v1", - description="API Documentation for my Blog Post", + description="API Documentation for my Blog", terms_of_service="https://github.com/okeneo/PersonalNest/blob/main/LICENSE", contact=openapi.Contact("okenetega@gmail.com"), license=openapi.License("MIT License"), diff --git a/backend/post/views.py b/backend/post/views.py index 634274e..0f87524 100644 --- a/backend/post/views.py +++ b/backend/post/views.py @@ -1,5 +1,6 @@ from account.permissions import IsAdminUser, IsAuthor, IsOwner, ReadOnly from django.utils import timezone +from drf_yasg.utils import swagger_auto_schema from rest_framework import status from rest_framework.generics import ListAPIView, get_object_or_404 from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly @@ -21,14 +22,28 @@ class PostListView(APIView): authentication_classes = (JWTAuthentication,) permission_classes = (ReadOnly | (IsAuthenticated & IsAuthor),) + @swagger_auto_schema( + responses={ + 200: PostDetailSerializer(many=True), + } + ) def get(self, request, *args, **kwargs): """Get all posts.""" posts = Post.objects.all() serializer = PostDetailSerializer(posts, many=True) return Response(serializer.data, status=status.HTTP_200_OK) + @swagger_auto_schema( + request_body=PostWriteSerializer, + responses={ + 201: PostWriteSerializer, + 400: "Bad Request", + 401: "Unauthorized Request", + }, + ) def post(self, request, *args, **kwargs): """Create a new post. + The user must be logged in (authenticated) and be an author. """ # TODO: They must be creating a post under their account. @@ -43,12 +58,27 @@ class PostDetailView(APIView): authentication_classes = (JWTAuthentication,) permission_classes = (ReadOnly | (IsAuthenticated & (IsAdminUser | (IsAuthor & IsOwner))),) + @swagger_auto_schema( + response={ + 200: PostDetailSerializer, + 401: "Unauthorized Request", + 404: "Post Not Found", + } + ) def get(self, request, pk, *args, **kwargs): """Get a post.""" post = get_object_or_404(Post, pk=pk) serializer = PostDetailSerializer(post) return Response(serializer.data, status=status.HTTP_200_OK) + @swagger_auto_schema( + response={ + 200: PostWriteSerializer, + 400: "Bad Request", + 401: "Unauthorized Request", + 404: "Post Not Found", + } + ) def put(self, request, pk, *args, **kwargs): """Update a post. @@ -61,6 +91,13 @@ def put(self, request, pk, *args, **kwargs): return Response(serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + @swagger_auto_schema( + response={ + 200: "Sucessful Response", + 401: "Unauthorized Request", + 404: "Post Not Found", + } + ) def delete(self, request, pk, *args, **kwargs): """Delete a post. @@ -68,13 +105,21 @@ def delete(self, request, pk, *args, **kwargs): """ post = get_object_or_404(Post, pk=pk) post.delete() - return Response({"detail": "Post deleted successfully."}, status=status.HTTP_204_NO_CONTENT) + return Response({"detail": "Post deleted successfully."}, status=status.HTTP_200_OK) class PublishPostView(APIView): authentication_classes = (JWTAuthentication,) permission_classes = (IsAuthenticated & (IsAdminUser | (IsAuthor & IsOwner)),) + @swagger_auto_schema( + responses={ + 200: "Successful Response", + 400: "Bad Request", + 401: "Unauthorized Request", + 404: "Post Not Found", + } + ) def post(self, request, pk, *args, **kwargs): """Publish an existing post.""" post = get_object_or_404(Post, pk=pk) @@ -91,20 +136,15 @@ def post(self, request, pk, *args, **kwargs): ) -class CategoryListView(ListAPIView): - queryset = Category.objects.all() - serializer_class = CategorySerializer - - -class TagListView(ListAPIView): - queryset = Tag.objects.all() - serializer_class = TagSerializer - - class PostCommentsView(APIView): authentication_classes = (JWTAuthentication,) permission_classes = (IsAuthenticatedOrReadOnly,) + @swagger_auto_schema( + responses={ + 200: CommentTreeSerializer(many=True), + } + ) def get(self, request, pk, *args, **kwargs): """Get all comments under a post.""" post = get_object_or_404(Post, pk=pk) @@ -127,6 +167,13 @@ def get(self, request, pk, *args, **kwargs): def put(self, request, pk, *args, **kwargs): pass + @swagger_auto_schema( + responses={ + 200: "Successful Response", + 401: "Unauthorized Request", + 404: "Comment Not Found", + } + ) def delete(self, request, pk, *args, **kwargs): """Delete a comment.""" comment = get_object_or_404(Comment, pk=pk) @@ -135,3 +182,29 @@ def delete(self, request, pk, *args, **kwargs): comment.soft_delete() else: comment.delete() + + +class CategoryListView(ListAPIView): + queryset = Category.objects.all() + serializer_class = CategorySerializer + + @swagger_auto_schema( + Categorys=["post"], + operation_description="List all categories.", + responses={200: CategorySerializer(many=True)}, + ) + def list(self, request, *args, **kwargs): + super().list(request, *args, **kwargs) + + +class TagListView(ListAPIView): + queryset = Tag.objects.all() + serializer_class = TagSerializer + + @swagger_auto_schema( + tags=["post"], + operation_description="List all tags.", + responses={200: TagSerializer(many=True)}, + ) + def list(self, request, *args, **kwargs): + super().list(request, *args, **kwargs)