할 일 그룹 목록 구현
시리즈, 입문
2024. 7. 3. AM 10:25:31
기본 구현
임시로 구현한 할 일 그룹 목록 페이지를 정식으로 구현해볼게요.
(1) TodoGroupService에 findall() API 구현
할 일 그룹을 조건에 맞게 검색하는 API인
findall()
메서드를
TodoGroupService
에 구현할게요. 최소한으로 필요한 검색 조건은 바로 특정 사용자지요.
Result
객체의
scalars()
를 사용하고,
ScalarResult
객체의
all()
메서드를 사용한 점을 제외하면 기존
select()
구문 생성 및 데이터 질의(querying) 구현과 다르지 않아요. 질의 결과가 복수 개이므로 스칼라 값을
scalars()
로 가져오고, 가져온 스칼라 값 모두를 가져온 것이지요. 만약 데이터가 매우 많다면 파티셔닝(
partitions()
)이나 페이징(Paging) 기법을 쓰는 게 좋아요.
구현한 코드 커밋 :
afee423
(2) 할 일 그룹 목록 페이지 종단점 함수 구현
앞서 임시로 작성한 코드에
findall()
로 할 일 그룹 목록을 가져오는 구현을 추가했어요. 간단하죠?
구현한 코드 커밋 :
17febca
(3) 할 일 그룹 목록 출력
데이터베이스에서 할 일 그룹 목록을 가져왔으니
todo-group-list.jinja2
템플릿 파일을 수정해 할 일 그룹 목록을 나열해볼게요.
잘 동작하죠? 이제 좀 모양이 나오네요! 😀

작성한 코드 커밋 :
2f4cd5c
비동기로 할 일 그룹의 할 일 개수 가져와 표시하기
(1) htmx로 지연 로딩과 부분 렌더링 구현
할 일 그룹명을 출력하고 그 옆에 해당 그룹에 존재하는 할 일 개수를 출력했는데요. 이 코드는 데이터베이스에 부하를 일으키는 동작을 할 가능성이 커요. 단순히 개수만 표시하면 되는데,
group.todos|length
는 데이터베이스에서 해당 할 일 그룹에 관계 맺은 할 일 데이터를 모두 가져온 후 Python 영역에서 개수를 세기 때문이죠. 불필요한 데이터를 모두 가져오는 부분에서 한 번, 그리고 Python에서 데이터 개수를 세는 부분에서 또 한 번 성능 저하가 일어나는 거예요.
이 부분을 htmx로 단순한 방식으로 개선해볼게요. 방식은 다음과 같아요.
-
할 일 그룹 목록 페이지에 접속
-
할 일 그룹 이름이 화면에 표시되면
-
각 할 일 그룹 별로 할 일 개수를 출력하는 API를 비동기로 호출
-
호출 결과를 할 일 그룹 이름 옆에 표시
htmx를 이용하면 아주 간단하게 구현할 수 있어요. 먼저
pages/todo-group-list.jinja2
템플릿을 수정해 htmx 구현을 적용할게요.
htmx 코드 두 줄만으로 네 단계를 구현했어요.
hx-trigger="load delay:250ms"
는 해당 HTML Dom 요소가 화면에 드러나면 0.25초 후에 작업을 수행하는 거예요.
htmx가
"partial-todo-group-todos-count"
라 이름붙은 URL을 호출해요. 이 HTTP API를 구현해야겠어요.
@tpl.hx()
장식자가 새롭게 등장했어요.
hx()
장식자는 FastHX에서 제공하는 메서드로, htmx 요청인 HTTP Request만 허용해요. 이런 설정이
page()
장식자엔 없어요.
(2) 할 일 그룹 별 할 일 개수 가져오기
TodoService
에
count_by_group_id()
API를 새롭게 추가해야 해요. 이름 그대로 할 일 그룹 ID(기본키 값)으로 할 일 개수를 세는 동작을 하죠. 근데 남의 할 일 그룹 ID를 알면 남의 할 일 개수도 알아낼 수 있잖아요? 그래서 이 API를 호출하는 사용자의 ID(기본키값)도 데이터 질의 검색 조건에 추가할 거예요.
조금 생소할 수 있는데, 다음 SQL 질의문을 작성하는 코드예요.
참고로 의사 코드이며, 실제로 작성하는 SQL문은 다음과 같아요.
SQL
count(*)
에 해당하는 Python 코드가
func.count()
에요. SQLAlchemy에서 제공하는
func
객체는
Function API
인데, SQL 함수 구문을 생성해주지요.
Todo.group
모델 필드는
TodoGroup
모델에 대한 관계 필드예요. 자료형 각주와 달리
TodoGroup
모델 그 자체는 아니예요. 그래서
Todo.group.user_id == user_id
표현식을 사용하지 못하는데, SQLAlchemy는
has()
로 관계 필드에 대한 탐색(lookup) 연산을 수행해줘요.
Todo.group.has(TodoGroup.user_id == user_id)
는 다음 SQL문을 작성하지요.
개수를 셋으니 이를 템플릿으로 출력합니다.
pudding_todo/apps/todo/templates
디렉터리 안에 부분이라는 뜻으로
partial
디렉터리를 만들고, 이 디렉터리 안에
todo-group-todos-count.jinja2
파일로 템플릿을 만들어요.
페이지 렌더링 템플릿은
pages
디렉터리에, 부분 렌더링 템플릿은
partial
디렉터리에 배치한 거죠.

여기까지 진행한 코드 커밋 :
33fdfc1
목차
다른 컨텐츠 더 보기
-
[할 일 관리 서비스 만들며 FastAPI에 입문하기 [연재 완료]]할 일 목록 구현2024. 7. 3.
-
[할 일 관리 서비스 만들며 FastAPI에 입문하기 [연재 완료]]할 일(Todo) 생성2024. 6. 19.
-
[할 일 관리 서비스 만들며 FastAPI에 입문하기 [연재 완료]]SQLAlchemy Admin으로 Admin 구현하기2024. 6. 25.
-
[React에 입문하기 [연재 중]]사용자 정의 훅(Custom Hook) 테스트2025. 1. 5.
-
[할 일 관리 서비스 만들며 FastAPI에 입문하기 [연재 완료]]할 일, 취소 상태로 변경2024. 7. 10.