FastAPI로 다이어리 서비스 구축(2)

김재섭·2024년 10월 31일
post-thumbnail

지난 포스트에서는 FastAPI와 SQLAlchemy를 활용하여 다이어리 서비스의 기본 API를 구축하는 방법에 대해 알아보았습니다.

우리는 사용자가 다이어리를 생성하고 수정하며 삭제하는 기능을 구현했습니다.

이러한 기본 기능이 완성되었으니, 이번 포스트에서는 다이어리 조회 API와 사용자들이 다이어리를 더욱 풍성하게 활용할 수 있도록 돕는 좋아요 기능을 추가해보겠습니다.

이제 우리가 구축한 다이어리 API의 활용도를 높이기 위해, 다양한 방법으로 사용자가 다이어리를 검색하고 관리할 수 있는 기능들을 심도 깊게 살펴보도록 하겠습니다.

다이어리 조회 API (GET)

사용자가 특정 기간 동안 작성한 다이어리를 조회하는 API입니다. type 파라미터에 따라 리스트 형식으로 반환하거나 달력 형식으로 표시할 수 있습니다. 또한, 이 API는 is_deleted가 False인 다이어리만 반환하여 삭제된 다이어리는 제외합니다.

@router.get("/main")
async def get_diaries(type: str, date: str, db: Session = Depends(get_db)):
    year = date[:4]
    month = date[4:]

    # MySQL에서 연도와 월을 추출하기 위한 DATE_FORMAT 사용
    diaries = db.query(DiaryModel).options(joinedload(DiaryModel.images)).filter(
        func.DATE_FORMAT(DiaryModel.date, "%Y") == year,
        func.DATE_FORMAT(DiaryModel.date, "%m") == month,
        DiaryModel.is_deleted == False  # 삭제된 다이어리를 제외
    ).all()
    
    if type == "calendar":
        result = [
            {
                "id": diary.id,
                "date": diary.date.strftime("%Y-%m-%d"),
                "image": diary.images[0].image_url if diary.images else "띠로리로고",
                "bookmark": diary.like
            }
            for diary in diaries
        ]

    # 목록형 조회 (title 포함)
    elif type == "list":
        result = [
            {
                "id": diary.id,
                "date": diary.date.strftime("%Y-%m-%d"),
                "title": diary.title,
                "image": diary.images[0].image_url if diary.images else "띠로리로고",
                "bookmark": diary.like
            }
            for diary in diaries
        ]

type 파라미터에 list 또는 calendar 중 하나를 선택하여 다이어리를 조회합니다.
date 파라미터는 YYYYMM 형식으로 전달되어 해당 월의 데이터를 조회합니다.
list 형식은 다이어리의 제목과 함께, calendar 형식은 날짜 정보만 반환하여 각 뷰의 필요에 맞게 데이터를 제공합니다.

다이어리 좋아요 기능

@router.put("/like/{diary_id}")
async def like_diary(diary_id: int, db: Session = Depends(get_db)):
    diary = db.query(DiaryModel).filter(DiaryModel.id == diary_id).first()
    if not diary:
        raise HTTPException(status_code=404, detail="Diary not found")
    
    # 좋아요 상태를 토글
    diary.like = not diary.like
    db.commit()

like 필드는 Boolean 타입으로, 해당 다이어리가 좋아요 되었는지의 여부를 나타냅니다.
이미 좋아요가 설정된 경우 이를 해제하고, 그렇지 않다면 좋아요로 설정합니다.
데이터베이스에 상태를 업데이트하여 사용자 피드백을 즉각적으로 반영합니다.

profile
Upward Developer

0개의 댓글