flask 서버, ajax, mongoDB 이용해서 책 좋아요 페이지 만들기
📅 기간 : 2020.10.29 ~ 30
@app.route('/api/list', methods=['GET'])
def show_books():
result = list(db.bookshop.find({},{'_id':0}).sort('like', -1))
return jsonify({'result':'success','book_list':result})
list(db.bookshop.find({},{'_id':0}).sort('like', -1))
딕셔너리 형태를 like
키 기준으로 내림차순 정리함
list 안쪽에 sort가 있는거 조심!!
function showBooks() {
$('.book-list').empty();
$.ajax({
type: 'GET',
url: '/api/list',
data: {},
success: function (response) {
if (response['result'] === 'success') {
let books = response['book_list'];
for (let i = 0; i < books.length; i++) {
let title = books[i]['title'];
let img = books[i]['img'];
let desc = books[i]['desc'];
let author = books[i]['author'];
let like = books[i]['like'];
let url = books[i]['url'];
makeCard(title, img, desc, author, like, url);
}
}
}
})
}
showBooks()
함수는 $(function(){ showBooks()} );
로 화면 로딩될 때마다 실행되도록 함
전달사항은 없으니 GET
정보를 서버로부터 받아서 필요한 정보들을 변수에 각각 저장하고 makeCard
함수
추가박스를 열면 원하는 책을 추가할 수 있도록 만들었다.
단, yes24 홈페이지에서 책 상세페이지 링크를 넣어야 한다.
아직 이런 입력값들을 일반화시키는 부분은 공부를 못했다😂
차차 공부해나가야지!
@app.route('/api/list', methods=['POST'])
def post_book():
url_receive = request.form['url_give']
data = requests.get(url_receive)
soup = BeautifulSoup(data.text, 'html.parser')
target = soup.select_one('#yDetailTopWrap > div.topColLft > div.gd_imgArea > span > em > img')
img_url = target['src']
title = target['alt']
author = soup.select_one('span.gd_auth > a:nth-child(1)')
desc = soup.select_one('div.infoWrap_txtInner > textarea > b')
rate = soup.select_one('#spanGdRating > a > em')
if (desc == None) or (rate == None):
return jsonify({'result': 'success', 'msg':'이 책은 추가할 수 없어요ㅠㅠ'})
book = {
'url': url_receive,
'title': title,
'img': img_url,
'author': author.text,
'desc': desc.text,
'rate': rate.text,
'like': 0,
}
db.bookshop.insert_one(book)
return jsonify({'result': 'success', 'msg':'추가 완료!'})
유저가 입력한 url에서 필요한 정보 스크래핑
속성값 가져올때는 ['']
로, 태그 안의 값 가져올때는 .text
사용한다.
책마다 다른 건 다있어도 간혹 상세설명이나 평점이 없는 경우가 있는데 이럴 경우 None
에 .text
를 적용할 수 없다고 에러가 발생한다.
if (desc == None) or (rate == None):
로 예외처리해줬다.
클라이언트는 그냥 input 값을 받아와서 전달해주고, 서버에서 성공하면
alert 띄워주고 새로고침해준다.
책마다 좋아요, 별로에요 버튼으로 순위를 설정할 수 있다.
좋아요 누르면 (좋아요: X) 숫자가 +1
별로에요 누르면 숫자가 -1 된다.
처음에는 (좋아요:X, 별로에요:X)
이렇게 따로 구상했었는데, 두개를 따로 순위매기는 것도 애매하기도해서 그냥 +,-로 바꿨다.
이게 더 깔끔하고 의미도 잘 전달되는 듯하다.
@app.route('/api/like', methods=['POST'])
def like_book():
book_receive = request.form['book_give']
book = db.bookshop.find_one({'title':book_receive},{'_id':0})
new_like = book['like'] + 1
db.bookshop.update_one({'title':book_receive}, {'$set':{'like':new_like}})
return jsonify({'result': 'success', 'msg': '위로!'})
dislike
는 다 똑같고 숫자만 -1, 메세지: 아래로! 인것만 다르다.
버튼 눌러진 책의 이름을 받아서 서버에서 해당 책을 찾는다.
+1 해준 숫자를 새로운 변수에 담아 update_one
으로 수정해준다.
이때, $set:
이 수정해줄 부분 앞에 붙는 것 주의하자
onclick="likeBook('${title}')"
책 좋아요 버튼 누르면 작동하는 likeBook()
함수에 인자로 책 제목을 넘겨준다.
function likeBook(book)
전달된 인자를 매개변수로 받는다.
성공하면 메세지 띄우고, 새로고침한다.
프론트는 부트스트랩 프레임워크 사용했다.
내가 처음에 기본으로 넣어둔 db는 책 40권이고, 여기에 계속 추가 가능하다.
처음에 API 만들기 시작했을 땐, 이걸 어떻게 설계하고 서버, 클라이언트 다 만들고하나.. 싶었는데 좀 하다보니 어느정도 머리에 정형화가 되가는 느낌이다.
그리고 확실히 그냥 공부하는 것보다는 미니 프로젝트하면서 맨땅에 헤딩하면서 공부하는 것이 훨씬 도움이 많이 된다.
구글 최고.. 없는게 없다.
프로그래밍은 정말 자기주도학습이 중요한 분야란 걸 계속 느낀다.
힘내쟈💪🏻