본문 바로가기
FrameWork/FastAPI

Pagination

by mansoorrr 2024. 6. 3.

게시판 리스트의 갯수가 한없이 늘어날 수 없으므로 페이징 기능을 구현한다.

 

[더미데이터 추가]

  • python shell을 이용해 더미데이터 300개 추가
from models import Question
from database import SessionLocal
from datetime import datetime


db = SessionLocal()
for i in range(300):
	q = Question(subject="테스트데이터 [%03d] % i", content="내용무", create_date=datetime.now())
    db.add(q)
db.commit()

 

 

[질문목록 api수정]

  • 질문목록을 찾을때 [시작할 위치], [몇개씩 찾을지] 정보를 파라미터로 추가
  • 전체 목록 개수, 질문목록 리스트를 반환
# question_crud.py 수정

#skip(시작위치)과 limit(몇건씩) prameter추가
def get_questions(db:Session, skip:int=0, limit:int=10):
	question_list = db.query(Question).order_by(Question.create_date.desc())
	total = question_list.count() # 전체 내용물 갯수
	question_list = question_list.offset(skip).limit(limit).all() # 10개씩 
	return total, question_list # total과 question_list 반환

 

  • question_crud에서 total과 question_list 두개를 반환하기 때문에 schema새로 생성
  • question_router 수정: page와 size를 parameter로 추가하고 get_questions함수에 skip, limit인자를 채워줌
# ---------- question_schema.py 추가
class QuestionList(BaseModel):
	total: int = 0
    question_list = list[Question] = []


# ---------- question_router.py 수정
@router.get('list', response_model=question_schema.QuestionList)
def question_list(db:Session=Depends(get_db), page:int=0, size:int=10):
	total, question_list = question_crud.get_questions(db=db, skip=page*size, limit=size)
    return {'total': total, 'question_list': question_list}

 

  • backend docs확인: 스키마대로 잘 나오는것을 확인 가능

 

 

[frontend 수정]

  • Home.svelte수정: fastapi함수에서 success_callback부분의 json을 json.question_list로 변경
// Home.svelte

  let question_list = []
  fastapi('get', '/api/question/list', {}, (json) => {
    question_list = json.question_list // 이부분 수정
  })

 

  • 페이지 기능 추가: 페이지는 url에서 'http:127.0.0.1:8000/api/question/list?page=0&size=10' 형식으로 호출되게 된다. 이렇게 호출하기 위해 api.js에서 operation="get"일 경우 params={}를 전달하면 new URLSearchParams를 이용해 url을 위의 형식으로 변환하게 했다.
  • 이부분을 적용하기 위해 get_question_list라는 함수를 만들어 주고 실행한다.
  • 가변변수 사용: $:를 활용해 업데이트되는 변수임을 나타내준다.
// Home.svelte

<script>
let question_list = []
let page = 0
let size = 10
let total = 0
$:total_page = Math.ceil(total/size) // $:를 이용해 반응형 변수 만들기(올림)

function get_question_list(_page) {
	//params 만들기
	let params = {
    	page = _page,
        size = size
    }
    // 함수에 params적용
    fastapi('get', '/api/question/list', params, (json) => {
    	question_list = json.question_list
        total = json.total
        page = _page
    })
}

get_question_list(0)
</script>

 

  • 표 하단에 페이지네이션 만들어줌
<ul class="pagination justify-content-center">
    // 이전페이지
    <li class="page-item {page<=0 && 'disabled'}">
    	<button>이전</button>
    </li>


    // 페이지번호
    {#each Array(total_page) as _, loop_page}
    <li class="page-item">
    	<button class="page-link" on:click={() => {get_question_list(loop_page)}}>{loop_page + 1}</button>
    </li>
    {/each}
    

    // 다음페이지
    <li class="page-item {page >= total_page-1 && 'disabled'}">
    	<button>다음</button>
    </li>
</ul>

 

  • 모든 페이지가 다 가능하므로 코드를 살짝 수정한다
  • loop_page기준 양옆으로 5개만 보이게 만듬
<!-- 페이지번호 -->
    {#each Array(total_page) as _, loop_page }
    {#if loop_page >= page-5 && loop_page <= page+5}
    <li class="page-item {loop_page === page && 'active'}">
      <button class="page-link" on:click={() => {get_question_list(loop_page)}}>{loop_page+1}</button>
    </li>      
    {/if}
    {/each}

'FrameWork > FastAPI' 카테고리의 다른 글

moment(날짜 포맷 변경)  (0) 2024.06.04
Svelte Store  (0) 2024.06.04
Error components  (0) 2024.06.03
svelte 부트스트랩 적용  (0) 2024.06.03
svelte 부트스트랩 적용  (0) 2024.06.03