Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database #77

Merged
merged 16 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배포용으로 바꾸신거죠?

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/"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클라우드 프론드 대신에 엔드포인트 추가

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),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엔드포인트 앞에 api 명시해서 우선순위 구분

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 @@ -57,52 +57,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:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예외처리..?

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()),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아이디 추가

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으로 설정)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시간설정

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):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

post내용에 스택 아이디 추가

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",
),
]
Loading