diff --git a/config/sort_options.py b/config/sort_options.py new file mode 100644 index 0000000..1672cce --- /dev/null +++ b/config/sort_options.py @@ -0,0 +1,7 @@ +DES_CREATEDATE = 'DES_CREATE_DATE' +ASC_CREATEDATE = 'ASC_CREATE_DATE' + +DATE_SORT_MAPPER = { + 'DES_CREATE_DATE': '-createDate', + 'ASC_CREATE_DATE': 'createDate' +} \ No newline at end of file diff --git a/diary/serializers.py b/diary/serializers.py index 40677c8..57c9ba9 100644 --- a/diary/serializers.py +++ b/diary/serializers.py @@ -1,6 +1,7 @@ from rest_framework import status from config.validator import positive_value +from config.sort_options import * from users.models import User from users.serializers import UserSafeSerializer from users.validator import exist_user_id @@ -156,3 +157,29 @@ class AnswerSerializer(serializers.Serializer): class AnswerListRequest(serializers.Serializer): answers = AnswerSerializer(many=True) + + +class CheckDiaryEntriesRequest(serializers.Serializer): + userId = serializers.IntegerField(validators=[exist_user_id]) + year = serializers.IntegerField(validators=[positive_year]) + month = serializers.IntegerField(validators=[positive_month]) + +class GetDiaryByUserAndDateRequest(serializers.Serializer): + userId = serializers.IntegerField(validators=[exist_user_id]) + startDate = serializers.DateField() + finishDate = serializers.DateField() + sortBy = serializers.ChoiceField(choices=[key for key in DATE_SORT_MAPPER.keys()], + required=False, + default=DES_CREATEDATE, + validators=[positive_sort_by]) + +class GetDiaryByUserAndDateResponse(serializers.Serializer): + user = UserSafeSerializer() + diaries = DiaryResultResponse(many=True) + + @staticmethod + def to_json(user_data, diaries_data): + return { + 'user': user_data, + 'diaries': diaries_data + } \ No newline at end of file diff --git a/diary/urls.py b/diary/urls.py index dd178c2..cafc440 100644 --- a/diary/urls.py +++ b/diary/urls.py @@ -9,4 +9,6 @@ path('//graph', GetNodeData.as_view()), path('/user/', GetDiaryByUserView.as_view()), path('/checkanswer', CheckAnswerView.as_view()), + path('/check', CheckDiaryEntriesView.as_view()), + path('/list', GetDiaryByUserAndDateView.as_view()), ] diff --git a/diary/validator.py b/diary/validator.py index bccd987..3d2a657 100644 --- a/diary/validator.py +++ b/diary/validator.py @@ -1,6 +1,7 @@ from rest_framework import serializers from diary.models import Diary, Keywords +from config.sort_options import DATE_SORT_MAPPER def exist_diary_id(diary_id): @@ -16,3 +17,18 @@ def not_exist_diary_date(user_id, date): def exist_keyword_id(keyword_id): if not Keywords.objects.filter(id=keyword_id).exists(): raise serializers.ValidationError(f'keywordId: {keyword_id} 가 존재하지 않습니다.') + + +def positive_month(month): + if month < 0 or month > 12: + raise serializers.ValidationError(f'month의 입력이 잘못되었습니다.') + + +def positive_year(year): + if len(str(year)) is not 4: + raise serializers.ValidationError(f'year의 입력이 잘못되었습니다.') + + +def positive_sort_by(value): + if value not in DATE_SORT_MAPPER.keys(): + raise serializers.ValidationError(f'sortBy 값이 유효하지 않습니다.') \ No newline at end of file diff --git a/diary/views.py b/diary/views.py index b7cbff8..8e9e371 100644 --- a/diary/views.py +++ b/diary/views.py @@ -5,11 +5,13 @@ from config.basemodel import ApiResponse, validator from config.settings import REQUEST_BODY, REQUEST_PATH, REQUEST_QUERY +from config.sort_options import DATE_SORT_MAPPER from diary.serializers import * from users.models import User from .graph import GraphDB from .graph_serializer import GraphDataSerializer +import calendar class DiaryCRUDView(APIView): @transaction.atomic @@ -249,3 +251,79 @@ def get(self, request): result=KeywordResultSerializer(findKeywords, many=True).data, response_status=status.HTTP_200_OK ) + + +class CheckDiaryEntriesView(APIView): + @transaction.atomic + @swagger_auto_schema( + operation_id="기간별 일기 유무 리스트 가져오기", + operation_description="기간별 일기 유무 리스트 가져오기", + query_serializer=CheckDiaryEntriesRequest(), + responses={status.HTTP_200_OK: ApiResponse.schema(ApiResponse)} + ) + @validator(request_type=REQUEST_QUERY, request_serializer=CheckDiaryEntriesRequest, return_key='query') + def get(self, request): + # 요청 데이터에서 userId, year, month 추출 + userId = request.query.validated_data.get('userId') + year = request.query.validated_data.get('year') + month = request.query.validated_data.get('month') + + # 해당 월의 일수를 가져옴 + _, lastDay = calendar.monthrange(year, month) + + # 일기가 존재하는 날짜를 dict으로 초기화 + diary_dict = {day: {"isExist": False, "diaryId": None} for day in range(1, lastDay + 1)} + + # 해당 userId, year, month에 해당하는 일기를 조회 + diaries = Diary.objects.filter(user_id=userId, createDate__year=year, createDate__month=month) + + # 조회된 일기의 날짜를 boolean 배열에 반영 + for diary in diaries: + diary_dict[diary.createDate.day]["isExist"] = True + diary_dict[diary.createDate.day]["diaryId"] = diary.id + + # 결과를 JSON 형식으로 반환 + result = {f'{year}-{month}': diary_dict} + return ApiResponse.on_success( + result=result, + response_status=status.HTTP_200_OK + ) + +class GetDiaryByUserAndDateView(APIView): + @transaction.atomic + @swagger_auto_schema( + operation_id="기간별 일기 리스트 가져오기", + operation_description="기간별 일기 리스트 가져오기", + query_serializer=GetDiaryByUserAndDateRequest(), + responses={status.HTTP_200_OK: ApiResponse.schema(ApiResponse)} + ) + @validator(request_type=REQUEST_QUERY, request_serializer=GetDiaryByUserAndDateRequest, return_key='query') + def get(self, request): + # 요청 데이터에서 userId, year, month 추출 + userId = request.query.validated_data.get('userId') + startDate = request.query.validated_data.get('startDate') + finishDate = request.query.validated_data.get('finishDate') + sortBy = request.query.validated_data.get('sortBy') + + sortField = DATE_SORT_MAPPER.get(sortBy) + + # 해당 userId, startDate, finishDate에 해당하는 일기를 조회 + diaries = Diary.objects.filter( + user_id=userId, + createDate__range=[startDate, finishDate] + ).order_by(sortField) + + # 해당 userId를 가지고 있는 유저 정보 가져오기 + user = User.objects.get(id=userId) + + # 유저 정보를 UserSafeSerializer를 사용해서 구조화 + user_info = UserSafeSerializer(user).data + # 일기 정보를 DiaryResultResponse를 사용하여 직렬화 + diary_list = DiaryResultResponse(diaries, many=True).data + + result = GetDiaryByUserAndDateResponse.to_json(user_data=user_info, diaries_data=diary_list) + + return ApiResponse.on_success( + result=result, + response_status=status.HTTP_200_OK + )