목록으로
할 일 목록 구현
할 일 그룹 별 할 일 목록 구현
할 일은 할 일 그룹 단위로 나열할 거예요. 할 일 그룹 목록을 구현하는 것과 거의 동일한데, 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
푸딩캠프 뉴스레터를 구독하면 학습과 성장, 기술에 관해 요약된 컨텐츠를 매주 편하게 받아보실 수 있습니다.
목차