서버에서 데이터를 받아서 화면에 띄워보니 스크롤이 엄~청나게 길어진 화면이 나와버렸다. 이걸 원래는 page 1, 2, 3 이런식으로 분리하려고 했는데 그건 못했고 대신 더보기 버튼을 만들어서 버튼을 클릭했을때마다 데이터가 추가되는 형식을 적용했다.
페이지네이션(Pagination) 이란 한정된 네트워크 자원을 효율적으로 활용하기 위해 쿼리의 결과값으로 리턴된 리소스를 분할하여 전달 하는 것을 의미한다.
대부분의 웹페이지가 이 페이지네이션을 적용하여 데이터값을 분할, 페이지화하여 화면에 보여준다.
페이지네이션은 DB를 어떤 방식으로 사용했느냐에 따라 방법이 달라지는데 내 프로젝트에서는 mongoDB를 이용해서 페이지네이션을 적용했다.
limit 메서드는 find를 이용하여 몽고디비에서 데이터를 조회할때 유용하게 사용할 수 있는 메서드다. 내가 원하는 수만큼 불러올 도큐멘트(컬렉션에 담긴 데이터)의 수를 제한할 수 있다. 예를 들어 페이지를 도큐멘트 9개 단위로 끊고 싶다하면 DB명.컬렉션명.find().limit(9)
이라고 입력하면 된다.
db.collection_name.find().limit(num)
페이지네이션을 할때는 limit메서드 하나만으로는 불가능한데, 왜냐면 DB에서 데이터를 조회해서 가져올때 limit으로 리소스를 분할해서 가져오도록 설정을 하고 그 다음에 후속조치를 취하지 않으면 중복된 데이터를 계속 가져오게 된다. 이를 방지하기 위해 사용할 수 있는게 skip( )메서드이다.
이 메서드는 이름 그대로 내가 원하는 수 만큼의 데이터를 건너뛰게 하는 메서드다.
db.collection_name.find().limit(num).skip(num)
나는 데이터를 9개씩 받을 수 있게 페이지네이션을 했다.
먼저 page라는 변수를 설정해서 이 값은 클라이언트가 보내주는 값에 응답하게 만들었다. 클라가 page에 대한 정보를 url에 담아서 주면 서버측에서는 이 page의 값을 인식해서 다음 행동을 한다.
@app.route('/api/cleaning', methods=['GET'])
def item_cleaning():
page = int(request.args.get('page', 1))
limit = 9
offset = (page - 1) * limit
items = list(db.zerowastestore.find(
{'category': 'Cleaning'}, {'_id': 0})
.limit(limit).skip(offset))
return jsonify(items)
코드를 해석해보면 zerowastestore라는 컬렉션에서 카테고리가 cleaning인 값을 조회하는데 (id 제외하고), 이때 변수 limit 만큼 분할해서 데이터를 조회하고 offset이라는 변수만큼 건너뛴다.는 내용이다.
그리고 offset 변수는 (page-1)*limit 값이기 때문에 page가 1일때는 건너뛰는 데이터값 0, 페이지가 2일때는 건너뛰는 데이터값 9, 그다음은 18 이런식의 구조를 취한다.
🎈참고하기
request.args.get(' ')
: GET 요청 방식에서 클라이언트로부터 전달받은 값을 읽는 방식
request.form[' ']
: POST 요청 방식에서 클라이언트로부터 전달받은 값을 읽는 방식
클라이언트에서는 아까 위에서 만들었던 page에 대한 정보를 url에 담아서 요청해야한다. 그리고 이 page의 숫자가 늘어나는건 '더보기'라는 버튼을 html에 만들고 이 버튼에 대한 onclick 함수에 넣어주면 된다.
'더보기' 버튼을 클릭했을때 페이지수가 1씩 늘어나면서 이 정보를 url에 담아서 서버에 데이터 요청을 하는것이다.
function getCleaning() {
$.ajax({
url: `/api/cleaning?page=${pageNo}`,
type: "GET",
data: {},
success: function (response) {
if (pageNo === 1) {
$("#products-area").empty();
}
.... 생략
$("#products-area").append(html);
}
})
}
function loadMore() {
pageNo += 1;
getCleaning();
}
참고
요청이 성공했을때 가장 먼저 실행되는 결과로 아래 함수를 넣은 이유는,
기존에 불러온 정보가 중복으로 존재하지 않도록 페이지수가 1일때 어펜딩했던 html 태그들을 깨끗하게 비우게 하기 위해서!
if (pageNo === 1) {
$("#products-area").empty();
}
무튼 결과는 아래같이 만들었다. 버튼을 눌렀을때 상품 9개가 추가된다.ㅎㅎ
그나저나 css 디테일 수정은 언제하지...
참고 링크:
mongoDB 튜토리얼