목록으로

할 일 목록 구현

시리즈, 입문
2024. 7. 3. AM 10:29:20

할 일 그룹 별 할 일 목록 구현

할 일은 할 일 그룹 단위로 나열할 거예요. 할 일 그룹 목록을 구현하는 것과 거의 동일한데, SQLAlchemy를 학습하는 목적으로 조금 다르게 구현해보겠습니다.

(1) 할 일 목록 템플릿 작성

대개 저는 템플릿을 마지막에 작성하는데, 설명을 위해 템플릿부터 작성할게요. pudding_todo/apps/todo/templates/pages 경로에 todo-list.jinja2 템플릿 파일을 만드세요.
완료하기, 취소하기 등 버튼은 다음 컨텐츠에서 구현할 거예요. 이 버튼을 제외하면 특이사항은 없지요?

(2) 할 일 목록 종단점 구현

할 일 목록 종단점 함수 구현도 특별히 다르지 않아요. 여태껏 구현해온 구현을 조합하는 거죠. 😀

(3) 할 일 그룹 별로 할 일 목록 페이지 링크

할 일 목록 페이지 구현까지 마쳤으니 할 일 그룹명을 누르면 이 페이지로 접속하도록 URL을 연결합니다. pudding_todo/apps/todo/templates/pages/todo-group-list.jinja2 템플릿 파일을 다음과 같이 수정할게요.

(4) 할 일 그룹별 할 일들 가져오기

이제 종단점 함수가 동작하도록 TodoService findall() API를 구현할 차례예요. 사용자의 할 일 그룹을 지정하면 그 그룹에 속한 할 일을 가져오는 API를 TodoService 에 구현합니다.
할 일 그룹 별 할 일 개수를 세는 count_by_group_id() 메서드와 다르게 구현했어요. offset limit 말고요. 😅 count_by_group_id() 메서드에서는 Todo.group.has() 표현식을 사용했는데, 이번엔 join() 을 사용했어요. 동작은 동일한데, SQL 질의문은 달라요.
먼저 .where(Todo.group.has(TodoGroup.user_id == user_id) 방식으로 생성된 SQL 질의문은 다음과 같아요.
.join() 방식으로 생성된 SQL 질의문은 다음과 같아요.
전혀 다르지요? SQLAlchemy의 장점이자 어려운 점이 바로 이런 점이라 생각해요. SQL 질의문을 Python으로 작성하듯이 세세하게 제어할 수 있지만, 그렇기 때문에 SQL문이나 데이터베이스을 잘 알지 못하면 동작은 하지만 상황에 적합하지 않은 SQL문을 작성할 수 있는 거죠.
join() 을 빠뜨리면 어떻게 동작할까요?
이렇게 말이죠. 아무 차이가 없어요. 물론 SQL 질의문은 달라요.
두 개 테이블에 질의를 보내기 때문에 이런 SQL 질의문을 수행하면 데이터가 두 개가 노출돼요. 다음과 같이요.
그래서 명시적으로 join() 을 사용해 테이블 JOIN 의도를 드러내야 합니다. 또는 result.unique() 와 같이 ScalarResult 객체의 unique() 메서드를 호출하여 중복되어 드러난 데이터를 하나로 걸러낼 수도 있어요. 최종 동작 결과는 동일한데요. join() 은 SQL 질의문에 JOIN을 하여 todo 테이블에 대해서만 데이터를 가져오는 것이라서 데이터가 중복되어 드러나지 않은 것이고, unique() 는 중복되어 데이터를 가져온 걸 Python 영역에서 걸러내는 큰 차이가 있어요.
여기까지 진행한 코드 커밋 : 9a55673
목차