ASAC-SK플래닛 T아카데미 데이터 엔지니어

25.11.04 19일차 [fastapi_대시보드 구성 추가, 수정, html 검색창 만들기]

Datadesigner 2025. 11. 4. 13:02

오늘은 기존에 대시보드에 추가한 데이터를 템플릿 라이브러리에 불러와서 올리고

 

쿼리를 수정하면서 출력되는 데이터값을 바꾸고,

 

쿼리 매개변수를 활용하여 페이지마다 다른 데이터가 나오는 실습과

 

검색창을 만들고 검색 버튼, 엔터버튼과 그 버튼을 눌렀을 때 상호작용하는 실습을 진행하였다.

 


1. 대시보드에 추가한 데이터를 템플릿 라이브러리에 대입하기
어제까지 수행한 실습

 

adminLTE사이트

먼저 adminLTE 사이트에서 개발자도구(SHIFT+CTRL+L)을 눌러서 가져올 테이블을 눌러본다.
그러면 그 테이블을 구성하는 코드를 찾을수 있다.
화면상 오른쪽 콘솔칸에 회색 코드이다. 이것을 접어서 복사한다, 요소복사하기로 해야된다.

header 부분
body 부분

읽어보면 알겠지만 header부분이 화면상 테이블의 위쪽 부분을, body부분이 밑의 표 부분을 구성한다.
이를 우리 데이터에 맞게 수정한다.

우리 header 부분

먼저 이름을 바꿔주고 searchInput id를 입력해준다. 아이디를 입력해야 나중에 #SerarchInput 키를 가진 값을 찾아낼 수 있다. 
input부분은 버튼에 관련된 코드이다. 이 곳에도 우리가 찾을 수 있게 searchBtn id 를 추가해준다.
우리는 실제 작동하게, 그리고 데이터를 불러올 수 있게 id를 추가해주어야 한다.

그리고 body부분에는 for문을 이용해서 각 컬럼의 데이터값을 모두 불러온다.

이렇게 페이지를 불러올 수 있다. 값은 다른 실습도 진행되서 조금은 다를 수 있다.
이 이미지를 테이블이라고 하는데 테이블에 회색 스트라이프 처리, 커서를 가져다대면 회색으로 상호작용하는 css등은 

51번 코드 테이블클래스다.
커서를 올리면 상호작용 한다, 2번째 데이터에 커서 올리고있다.

그런데 한 페이지에 모든 정보를 불러오면 안되잖아? 그래서 백엔드를 구성하는 함수또한 수정해줘야 한다.

 

 

2. 쿼리 수정, 백엔드 수정

__init__.py 파일
sql을 불러오는 파일인 __init__.py 파일을 수정했다.
기존의 쿼리에서 order by로 주문날짜로 내림차순으로 정렬했다, 그 이후 limit를 걸어서 변수에 할당되는 숫자만큼 출력이 되도록 변수를 추가했다. 그리고 맨 위 def에도 변수값을 세팅해주고 기본값을 주어서 다른 숫자를 url에 작성하지 않아도 기본값대로 출력되게 세팅하였다. %s가 키워드이다, 그냥 외워라
그 이후 메인이 되는 main.py 파일에서도 수정을 해준다.
함수값에 변수를 새로 설정해주고 출력되는 값에도 변수를 추가해준다, 이제 이 변수또한 읽으며 사이트에서 작동한다.
이제 http://127.0.0.1:8000/sales/board url에 뒤에 쿼리변수를 추가해서 이 값을 바꾸면 사이트도 다르게 작용하나?

한 페이지에 3개씩 100번째 페이지라는 뜻이다.

50개씩 첫페이지이다.
주소창에 ?를 반드시 붙여야 한다, 물음표 기호가 get을 칭하는 기호이다
아무것도 입력하지 않아도 기본값이 적용되는 모습이다,

이제 테이블상의 검색창이 작용하도록 해야한다.

 

3. 검색창 활성화

먼저 우리는 html 수정할때 검색창을 가져올 때 위 코드부분에 두 가지 id를 추가해줬다.
하나는 input이고 하나는 button이다.
input은 입력창, button은 검색버튼이다, 이 곳에 클릭 or 엔터를 인식하는 코드, 입력을 감지하는 코드를 추가해준다,

먼저 이렇게 작용하는 코드는 항상 바디가 끝나기 직전에 마지막 바로 위에 구성해야 한다, 그래야 오류가 나지 않는다.
그 이후 SearchInput은 document.querySelector('#SearchInput') 을 칭한다, 이게 다른 html에서 찾아서 불러온다.
마찬가지로 searchBtn에도 쿼리셀렉터를 불러준다, 이게 css selector 기능이다.
이게 검색창, 그리고 검색버튼을 특정지어주는 역할을 하고 코드가 실행될 수 있게 해준다,
그리고 검색버튼은 검색어를 서버로 보내서 결과를 받아오는 작업을 진행한다 -> 이후 결과를 화면에 반영한다.

클릭은 검색버튼 클릭이고, 엔터는 검색창에 값을 입력하고 엔터를 누른다, 우리가 흔히 검색하는것처럼,
그래서 엔터 클릭 코드는 SearchInput에서 가져오는 것이다.
그 다음은 클릭, 엔터를 뜻하는 명령어 click, keypress를 넣어준다,

이렇게 오른쪽아래 콘솔을 보면 엔터 클릭, 버튼 클릭이 돌아간다, 그런데 이상한 점은 아무키나 눌러도 엔터클릭 코드가 작동되는것을 볼 수 있다. 그래서 우린 if조건문을 사용해서 오직 엔터키만 작동하게 해줘야 한다.
엔터키를 누르면 keyCode가 13이다, 오직 keyCode가 13일때만 작동해야한다.
이후 searching() 함수가 돌아가도록 세팅할것이고 이 함수는 밑에서 세팅해준다.

이 때는 fetch라는 라이브러리를 사용했는데 이는 파이썬에 내장되어있는 라이브러리로 http 구성요소를 javascript에서 접근하고 조작하게 도와주는 인ㅌ터페이스를 제공한다.
서버에 전송하는 역할과 함께.
예외처리와 비슷한 역할을 하는 then catch finally를 사용하고 그 위에 fetch 라이브러리를 사용한다.
fetch api 라이브러리

우리는 바로 밑의 이 가이드라인을 따라간다.


이쪽은 그냥 외워야한다 

그래서 우리는 fetch가 실행되면
/sales/search/로 넘어가도록 했고
post방식을 사용하고
json으로 전송되도록 하고
js 객체형태 데이터를 문자열로 변환하도록 했다.
그리고 이게 성공하면 검색 성공, 작업 진행
실패하면 통신 실패, error출력
finally는 뒷정리다,

url을 추가했으니까 이제 뭘 해야하지?
백엔드에 /sales/search/를 추가해줘야지

 

4. 백엔드 수정

서버 메인이 되는 main.py 파일을열고 밑에 post방식 백엔드를 추가해준다.
url 추가는 많이 해봤으니 익숙하다.
전송할 데이터의 형식을 dict로 에너테이션 해주고
모델을 검색하면 받을 수 있도록 세팅할 예정이다.
이제 백엔드에서 db를 검색 후 결과값을 보낼 수 있도록 db 쿼리문을 만들어준다

쿼리문은 위에서 했던 내용과 비슷하게, 대신 달라진 점은 컬럼값을 우리가 정하였고, keyword라는 변수를 f포맷팅을 사용해서 입력받을 수 있게 만들었다.
keyword = SearchInput.values이다.클라이언트가 입력한 값을 keyword로 타고 온다,
이 과정은 html에서 이루어진다.
그 다음 데이터베이스상에서 keyword에 맞는 데이터뭉티기를 보내준다,
이 과정이 post이다, 그리고 키워드가 포함된 데이터를 찾기 위해서 like 문자열 함수를 사용해주었다.

그 다음 post로 html로 데이터를 뿌려줄 내용을 메인 .py에 만들어준다,
/sales/search/로 데이터를 보내줄 것이고 return값은 {results:select_order_by_model(data.get('query'))} 이다.
이 함수는 db상에서 데이터 뭉티기를 찾는 함수이고 이 함수에서 dict형식인, 그리고 key=query인 데이터를 results라는 이름으로 보내주는것이다.

이건 아까 위에 있던 fetch 라이브러리를 더 간편하게 사용한 방법이다.
필요한 부분만 가져오고 나머지 작용하는 파트는 밑에 빼두면 된다,
아까 가져온 results라는 데이터가 res에 객체 구조 분해로 할당되는것이다. 여기서 res또한 딕셔너리인데 
딕셔너리 + 딕셔너리인 {results}를 res에 담으며 한번 분해시켜주는거다.
그리고 이 내용들을 화면에 담는다.

 

 

5. 화면 처리 html수정
검색해서 나온 데이터를 html화면에 불러오려면 먼저 데이터를 불러오며 동시에
기존에 화면에 있는 데이터들을 지워야한다. 
그 기능이 84번줄에 있는 innerHTML이다.
이 기능은 HTML테이블에서 tbody를 특정짓고, 해당 요소의 하위요소를 제거한다
모두 ' ' 으로 삭제시켜버렸다.
그리고 html이라는 이름을 가진 변수를 하나 만든다, 일단 showDetail은 무시하고 나머자만 보면
sales라는 이름이 results의 딕셔너리이다. 같은 데이터다
그리고 sales.forEach 문으로 sale, index로 나누어서 모든 값을 각각의 위치에 부여한다.
그리고 html 변수에 데이터가 더해질때마다 누적되도록 연산자를 붙여서 값이 계속 쌓이도록 한다.
그 이후 for문을 계속 돌리는 코드를 붙여넣는다. 이 때 td값에 있는게 포맷팅되어서 sale [ 인덱스 ] 로 계속 불러와지는것이다.
그리고 마지막 코드는 새로 구성된 내용을 테이블의 자식 요소로 추가하는것이다,

이제 ma를 검색하면 엔터버튼을 인식해서 searching 함수가 작동해서 keyword ma가 쿼리문으로 넘어가서 like ma 인 ma가 포함된 모든 데이터들을 가져온다, 그리고 그 데이터들이 post방식으로 다시 html로 뿌려져서 searching 함수에서 딕셔너리형태 = 객체형태 로 다시 반환된다, 그리호 그렇게 들어온 데이터는 resetResultTable 함수로 들어오는데 이 함수는 밑에서 정의된 테이블에 데이터를 실제로 출력해주는 함수이다,
resetResultTable 함수에 들어간 객체형태의 데이터가 innerHTML이 먼저 기존의 데이터를 싹 지워주고 그 다음 FOReACH문을 통해서 테이블에 들어가게 된다. 정말 복잡하고 신기한 세상은요지경 데이터센터다
아무값도 입력하지 않으면 이렇게 된다,

 

6. 데이터 상세보기

이제 우리는 해당 정보를 클릭하면 그 주문번호의 상세페이지를 표현하는 기능을 추가할것이다
아까 위에 있던 showDetail 함수에 있던 onclick을 기억하시는가?
sales_board.py
onclick함수는 클릭 정보를 받는 함수다,
여기에 if문으로 해당 주문을 확인하시겠습니까 멘트의 알림창을 띄워준다.
그리고 밑에 있는 location.href함수가 저 위치로 사이트를 이동한다는 의미의 함수이다.
이렇게 /sales/detail/주문번호 로 이동하는 기능이 생겼다.

그 이후 쿼리를 먼저 만들어도 되고, 백엔드에서 먼저 수정해줘도 된다.
나는 쿼리문 함수를 먼저 만들어보겠다.

__init__.py
기본 틀은 이전에 썼던 함수를 그대로 가져오면 된다.
여기서 달라진 점은 쿼리문인데 주문 번호가 일치하는 데이터 한개의 데이터만 전체를 가져오는것으로 바뀌었다.
그렇게 select_order_detail 함수는 주문번호가 일치하는 데이터를 데이터베이스에서 가져와서 백엔드로 넘겨준다.

main.py
그리고 메인 파일에서 html로 뿌려준다.
여기서 order 를 select ... 함수가 가져온 데이터로 대치시킨다,
그리고 이 함수는 sales_detail.html을 참조한다. 
그럼 이제 sales_detail.html 을 만들어준다. 이 때 jinja2의 새로운 기능이 나온다.

메인 화면을 구성하는 index.html

 

index.html을 그대로 복사해서 가져오고, 이를 base.html이라고 이름붙인다.
그 이후 index_conents.html 본문 내용만 block contests / endblock 으로 바꿔준다.

sales_detail.html


맨 위에 extends "base.html" 을 붙이면 그 html 파일을 그대로 상속받아서 원판으로 사용한다.
이 파일 안에는 그냥 커스텀할 부분만 수정해서 넣어주면 기존 index.html 내용을 전부 가져오고 본문 내용만 빠진
그야말로 base 파일을 참조하는 것이다.
block contests / endblock  이 사이에 어떤 내용이 들어갈지 설정해준다. 이는 order로 칭한다.
order는 main.py에서 select... 함수가 가져온 데이터로 대치되어있다.
이렇게 하면 main.py에서 참조할 sales_detail.html 파일도 완성되었다.
이제 리스트에서 알림창을 눌러보자.

알림창 클릭
짜잔

현재 데이터가 들어갈 테이블 세팅을 하지 않아서 출력은 데이터 그대로 나온다.
이 후 진도는 내일 나간다고 한다.

내일 봅시다~