Skip to content

Commit

Permalink
Merge pull request #77 from OZ-Coding-School/database
Browse files Browse the repository at this point in the history
Database
  • Loading branch information
youngkwangjoo authored Jul 31, 2024
2 parents 462f82c + 334207c commit aece5e3
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 82 deletions.
7 changes: 4 additions & 3 deletions potato_project/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@

# 국제화 설정
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
TIME_ZONE = "Asia/Seoul"
USE_I18N = True
USE_TZ = True

Expand Down Expand Up @@ -201,9 +201,10 @@
"repo",
"read:org",
],
"ON_DELETE": "CASCADE",
}
}

SOCIALACCOUNT_LOGIN_ON_GET = True
LOGIN_REDIRECT_URL = "https://d3hcv7ngm54uy8.cloudfront.net/oauth-callback"
ACCOUNT_LOGOUT_REDIRECT_URL = "https://d3hcv7ngm54uy8.cloudfront.net/landing"
LOGIN_REDIRECT_URL = "/oauth-callback/"
ACCOUNT_LOGOUT_REDIRECT_URL = "/landing/"
26 changes: 13 additions & 13 deletions potato_project/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
from django.urls import include, path

urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/", include("dj_rest_auth.registration.urls")),
path("accounts/", include("dj_rest_auth.urls")),
path("accounts/", include("allauth.urls")),
path("accounts/", include("users.urls")),
path("baekjoons/", include("baekjoons.urls")),
path("attendances/", include("attendances.urls")),
path("potatoes/", include("potatoes.urls")),
path("potatoes/", include("potato_types.urls")),
path("stacks/", include("stacks.urls")),
path("stacks/", include("user_stacks.urls")),
path("todos/", include("todos.urls")),
path("githubs/", include("githubs.urls")),
path("api/admin/", admin.site.urls),
path("api/accounts/", include("dj_rest_auth.registration.urls")),
path("api/accounts/", include("dj_rest_auth.urls")),
path("api/accounts/", include("allauth.urls")),
path("api/accounts/", include("users.urls")),
path("api/baekjoons/", include("baekjoons.urls")),
path("api/attendances/", include("attendances.urls")),
path("api/potatoes/", include("potatoes.urls")),
path("api/potatoes/", include("potato_types.urls")),
path("api/stacks/", include("stacks.urls")),
path("api/stacks/", include("user_stacks.urls")),
path("api/todos/", include("todos.urls")),
path("api/githubs/", include("githubs.urls")),
]
5 changes: 4 additions & 1 deletion potato_project/potatoes/migrations/0002_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ class Migration(migrations.Migration):

dependencies = [
("potatoes", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
(
"users",
"__first__",
), # users 앱의 첫 번째 마이그레이션 파일을 dependency로 추가
]

operations = [
Expand Down
2 changes: 1 addition & 1 deletion potato_project/potatoes/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
urlpatterns = [
path("collection/", views.MyPotatoDetail.as_view(), name="potato_detail"),
path(
"patch/",
"select/",
views.PotatoSelectPatch.as_view(),
name="potato_select_patch",
),
Expand Down
50 changes: 11 additions & 39 deletions potato_project/potatoes/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,52 +56,24 @@ class PotatoSelectPatch(APIView):

def patch(self, request):
try:
potato = Potato.objects.filter(
user=request.user, data=request.data, partial=True
) # request.user 사용
potato_id = request.data.get("id")
potato = Potato.objects.get(id=potato_id, user=request.user)

if not potato.exists():
if not potato:
return Response(
{"detail": "Not found"}, status=status.HTTP_404_NOT_FOUND
)

if "is_selected" not in request.data:
return Response(
{"detail": "is_selected field is required"},
status=status.HTTP_400_BAD_REQUEST,
)

is_selected = request.data["is_selected"]
if is_selected:
# 유저가 가지고 있는 모든 감자의 is_selected 값을 False로
Potato.objects.filter(user=request.user).update(is_selected=False)

# 유저가 선택한 감자의 is_selected 값을 True로
serializer = PotatoSerializer(
potato.first(), data={"is_selected": is_selected}, partial=True
)
# 기존에 선택된 감자의 is_selected 값을 False로 변경
Potato.objects.filter(user=request.user).update(is_selected=False)
# 현재 선택된 감자의 is_selected 값을 True로 변경
potato.is_selected = True # 객체 속성 직접 변경
potato.save() # 변경 사항 저장

if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
serializer = PotatoSerializer(potato) # 업데이트된 객체 다시 가져오기
return Response(serializer.data)

except DatabaseError as e:
return Response(
{"error": "Database error occurred"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
except ValidationError as e:
return Response(
{"error": "Serialization error occurred", "details": e.detail},
status=status.HTTP_400_BAD_REQUEST,
)
except ObjectDoesNotExist as e:
return Response(
{"error": "Object does not exist", "details": str(e)},
status=status.HTTP_404_NOT_FOUND,
)
except Exception as e:
except Exception as e: # Exception handling remains the same
return Response(
{"error": "An unexpected error occurred", "details": str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
Expand Down
2 changes: 1 addition & 1 deletion potato_project/stacks/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

from . import views

urlpatterns = [path("all", views.StackList.as_view(), name="stack_list")]
urlpatterns = [path("all/", views.StackList.as_view(), name="stack_list")]
3 changes: 2 additions & 1 deletion potato_project/todos/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ class Meta:
class TodoCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Todo
# 생성 시에는 'is_done', 'date'는 자동으로 처리되므로 제외

fields = ["task", "date"] # 생성 시에는 'is_done'은 자동으로 처리되므로 제외
10 changes: 4 additions & 6 deletions potato_project/todos/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@

urlpatterns = [
path("create/", TodoCreateView.as_view()),
path("<int:pk>/update/", TodoUpdateView.as_view()),
path("<int:pk>/delete/", TodoDeleteView.as_view()),
path("todos/<int:pk>/done/", TodoMarkDoneView.as_view(), name="todo-mark-done"),
path(
"todos/<int:pk>/undone/", TodoMarkUndoneView.as_view(), name="todo-mark-undone"
),
path("<int:id>/update/", TodoUpdateView.as_view()),
path("<int:id>/delete/", TodoDeleteView.as_view()),
path("<int:id>/done/", TodoMarkDoneView.as_view(), name="todo-mark-done"),
path("<int:id>/undone/", TodoMarkUndoneView.as_view(), name="todo-mark-undone"),
path("today/", TodayTodoListView.as_view()),
path("<str:date>/", DailyTodoListView.as_view()), # 'YYYY-MM-DD' 형식
path(
Expand Down
39 changes: 32 additions & 7 deletions potato_project/todos/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime, timedelta

from django.db.models import Count, Q
from django.shortcuts import get_object_or_404
from django.utils import timezone
from rest_framework import generics, permissions, status
from rest_framework.permissions import IsAuthenticated
Expand All @@ -18,7 +19,12 @@ class TodoCreateView(generics.CreateAPIView):
def perform_create(self, serializer):
date_str = self.request.data.get("date") # 프론트엔드에서 전달된 날짜 문자열
try:
date = datetime.strptime(date_str, "%Y-%m-%d").date()
# datetime 객체 생성 (시간은 00:00:00으로 설정)
date_obj = datetime.strptime(date_str, "%Y-%m-%d").replace(
hour=0, minute=0, second=0, microsecond=0
)
# timezone-aware datetime 객체로 변환
date = timezone.make_aware(date_obj)
except (ValueError, TypeError):
return Response(
{"error": "Invalid date format or missing date."},
Expand All @@ -30,17 +36,25 @@ def perform_create(self, serializer):

# 2. 투두리스트 항목 수정 (UI에서 입력 받은 데이터 + 선택된 날짜로 수정)
class TodoUpdateView(generics.UpdateAPIView):
queryset = Todo.objects.all()
serializer_class = TodoSerializer
permission_classes = [IsAuthenticated]

def get_object(self):
todo_id = self.kwargs.get("id")
return get_object_or_404(Todo, id=todo_id, user=self.request.user)

def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)

def perform_update(self, serializer):
date_str = self.request.data.get("date")
try:
date = datetime.strptime(date_str, "%Y-%m-%d").date()
# datetime 객체 생성 (시간은 00:00:00으로 설정)
date_obj = datetime.strptime(date_str, "%Y-%m-%d").replace(
hour=0, minute=0, second=0, microsecond=0
)
# timezone-aware datetime 객체로 변환
date = timezone.make_aware(date_obj)
except (ValueError, TypeError):
return Response(
{"error": "Invalid date format or missing date."},
Expand All @@ -52,18 +66,25 @@ def perform_update(self, serializer):

# 3. 투두리스트 항목 삭제
class TodoDeleteView(generics.DestroyAPIView):
queryset = Todo.objects.all()
permission_classes = [IsAuthenticated]

def get_object(self):
todo_id = self.kwargs.get("id")
return get_object_or_404(Todo, id=todo_id, user=self.request.user)

def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)


# 4. 투두리스트 is_done True<->False
class TodoMarkDoneView(generics.UpdateAPIView):
queryset = Todo.objects.all()
permission_classes = [IsAuthenticated]
serializer_class = TodoSerializer
http_method_names = ["patch"] # PATCH 메서드만 허용

def get_object(self):
todo_id = self.kwargs.get("id")
return get_object_or_404(Todo, id=todo_id, user=self.request.user)

def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
Expand All @@ -74,9 +95,13 @@ def perform_update(self, serializer):


class TodoMarkUndoneView(generics.UpdateAPIView):
queryset = Todo.objects.all()
permission_classes = [IsAuthenticated]
serializer_class = TodoSerializer
http_method_names = ["patch"] # PATCH 메서드만 허용

def get_object(self):
todo_id = self.kwargs.get("id")
return get_object_or_404(Todo, id=todo_id, user=self.request.user)

def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
Expand All @@ -92,7 +117,7 @@ class TodayTodoListView(generics.ListAPIView):
permission_classes = [IsAuthenticated]

def get_queryset(self):
today = timezone.now().date()
today = timezone.localtime(timezone.now()).date()
return Todo.objects.filter(user=self.request.user, date__date=today)


Expand Down
2 changes: 1 addition & 1 deletion potato_project/user_stacks/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
name="user_stack_create",
),
path(
"delete/<int:stack_id>/",
"delete/<int:user_stack_id>/",
views.UserStackDelete.as_view(),
name="user_stack_delete",
),
Expand Down
28 changes: 20 additions & 8 deletions potato_project/user_stacks/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,24 @@ def get(self, request): # user_id 매개변수 제거
class UserStackCreate(APIView):
permission_classes = [IsAuthenticated]

def post(self, request): # user_id 매개변수 제거
serializer = UserStackSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user) # request.user 사용
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request):
stack_id = request.data.get("stack_id") # stack_id 받아오기

if not stack_id:
return Response(
{"error": "stack_id is required"}, status=status.HTTP_400_BAD_REQUEST
)

try:
user_stack = UserStack.objects.create(user=request.user, stack_id=stack_id)
return Response(
{"message": "UserStack created", "id": user_stack.id},
status=status.HTTP_201_CREATED,
)
except Exception as e:
return Response(
{"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
)


# # 유저 스택 업데이트
Expand Down Expand Up @@ -58,9 +70,9 @@ def post(self, request): # user_id 매개변수 제거
class UserStackDelete(APIView):
permission_classes = [IsAuthenticated]

def delete(self, request, stack_id):
def delete(self, request, user_stack_id):
try:
stack = UserStack.objects.get(user=request.user, id=stack_id)
stack = UserStack.objects.get(user=request.user, id=user_stack_id)
except UserStack.DoesNotExist:
return Response(
{"error": "Stack not found for this user"},
Expand Down
2 changes: 1 addition & 1 deletion potato_project/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class UserSerializer(ModelSerializer):
class Meta:
model = User
fields = [
"user_id",
"id",
"username",
"profile_url",
"github_id",
Expand Down
5 changes: 5 additions & 0 deletions potato_project/users/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@
views.UpdateBaekjoonIDView.as_view(),
name="update-baekjoon-id",
),
path(
"nickname/",
views.UserNicknameUpdateView.as_view(),
name="update-nickname",
),
]

0 comments on commit aece5e3

Please sign in to comment.