웹개발 플러스 3주차 숙제
한동안 일이 바빠서 저녁에 시간이 없었다.
뒤늦게 3주차 완주.
3주차 수업 내용은 쉬웠지만,
숙제를 보고 당황할 것 같은 느낌이었다.
웹 개발은 정말 안 친해지는 느낌...
그래도 애매하게 알았던 것들이 좀 더 명확해진 거 같다.
app.py
from flask import Flask, render_template, request, jsonify, redirect, url_for
from pymongo import MongoClient
app = Flask(__name__)
client = MongoClient('3.34.132.207', 27017, username="test", password="test")
db = client.dbsparta_plus_week3
@app.route('/')
def main():
return render_template("index.html")
@app.route('/matjip', methods=["GET"])
def get_matjip():
# 맛집 목록을 반환하는 API
matjip_list = list(db.matjips.find({}, {'_id': False}))
# print(len(matjip_list))
# matjip_list 라는 키 값에 맛집 목록을 담아 클라이언트에게 반환합니다.
return jsonify({'result': 'success', 'matjip_list': matjip_list})
@app.route('/add_favorite', methods=["POST"])
def add_favorite():
title = request.form["title"]
address = request.form["address"]
action = request.form["action"]
if action == "like":
db.matjips.update_one({"title": title, "address": address}, {"$set": {"liked": True}})
print("added")
else:
db.matjips.update_one({"title": title, "address": address}, {"$unset": {"liked": False}})
print("removed")
return jsonify({'result': 'success'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta property="og:title" content="스파르타 맛집 지도"/>
<meta property="og:description" content="mini project for Web Plus"/>
<meta property="og:image" content="{{ url_for('static', filename='og_image.jpg') }}"/>
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
<title>스파르타코딩클럽 | 맛집 검색</title>
<script type="text/javascript"
src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId={CLIENT_ID}=geocoder"></script>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<style>
.wrap {
width: 90%;
max-width: 750px;
margin: 0 auto;
}
.banner {
width: 100%;
height: 20vh;
background-image: url("{{ url_for('static', filename='banner.jpg') }}");
background-position: center;
background-size: contain;
background-repeat: repeat;
}
h1.title {
font-family: 'Jua', sans-serif;
color: white;
font-size: 3rem;
}
.matjip-list {
overflow: scroll;
width: 100%;
height: calc(20vh - 30px);
position: relative;
}
.card-title, .card-subtitle {
display: inline;
}
h5 {
font-family: 'Jua', sans-serif;
}
#map {
width: 100%;
height: 50vh;
margin: 20px auto 20px auto;
}
.iw-inner {
padding: 10px;
font-size: smaller;
}
i {
color: #e8344e;
}
i:hover {
cursor: pointer;
}
</style>
<script>
let y_cen = 37.4981125 // lat
let x_cen = 127.0379399 // long
let map;
let markers = [];
let infowindows = [];
$(document).ready(function () {
map = new naver.maps.Map('map', {
center: new naver.maps.LatLng(y_cen, x_cen),
zoom: 12,
zoomControl: true,
zoomControlOptions: {
style: naver.maps.ZoomControlStyle.SMALL,
position: naver.maps.Position.TOP_RIGHT
}
});
get_matjips();
})
function get_matjips() {
$('#matjip-box').empty();
$.ajax({
type: "GET",
url: '/matjip',
data: {},
success: function (response) {
let matjips = response["matjip_list"]
for (let i = 0; i < matjips.length; i++) {
let matjip = matjips[i]
// console.log(matjip)
make_card(i, matjip);
let marker = make_marker(matjip);
add_info(i, marker, matjip);
}
}
});
}
function make_card(i, matjip) {
let html_temp = ``;
if ("liked" in matjip) {
html_temp = `<div class="card" id="card-${i}">
<div class="card-body">
<h5 class="card-title"><a href="javascript:click2center(${i})" class="matjip-title">${matjip['title']}</a></h5>
<h6 class="card-subtitle mb-2 text-muted">${matjip['category']}</h6>
<i class="fa fa-bookmark" onclick="bookmark('${matjip['title']}', '${matjip['address']}', 'unlike')"></i>
<p class="card-text">${matjip['address']}</p>
<p class="card-text" style="color:blue;">${matjip['show']}</p>
</div>
</div>`;
} else {
html_temp = `<div class="card" id="card-${i}">
<div class="card-body">
<h5 class="card-title"><a href="javascript:click2center(${i})" class="matjip-title">${matjip['title']}</a></h5>
<h6 class="card-subtitle mb-2 text-muted">${matjip['category']}</h6>
<i class="fa fa-bookmark-o" onclick="bookmark('${matjip['title']}', '${matjip['address']}', 'like')"></i>
<p class="card-text">${matjip['address']}</p>
<p class="card-text" style="color:blue;">${matjip['show']}</p>
</div>
</div>`;
}
$('#matjip-box').append(html_temp);
}
function make_marker(matjip) {
let marker_img = '';
if ("liked" in matjip) {
marker_img = '{{ url_for("static", filename="marker-liked.png") }}'
} else {
marker_img = '{{ url_for("static", filename="marker-default.png") }}'
}
let marker = new naver.maps.Marker({
position: new naver.maps.LatLng(matjip["mapy"], matjip["mapx"]),
map: map,
icon: marker_img
});
markers.push(marker);
return marker
}
function add_info(i, marker, matjip) {
let html_temp = `<div class="iw-inner">
<h5>${matjip['title']}</h5>
<p>${matjip['address']}
</div>`;
let infowindow = new naver.maps.InfoWindow({
content: html_temp,
maxWidth: 200,
backgroundColor: "#fff",
borderColor: "#888",
borderWidth: 2,
anchorSize: new naver.maps.Size(15, 15),
anchorSkew: true,
anchorColor: "#fff",
pixelOffset: new naver.maps.Point(10, -10)
});
infowindows.push(infowindow)
naver.maps.Event.addListener(marker, "click", function (e) {
if (infowindow.getMap()) {
infowindow.close();
} else {
infowindow.open(map, marker);
map.setCenter(infowindow.position)
$("#matjip-box").animate({
scrollTop: $("#matjip-box").get(0).scrollTop + $(`#card-${i}`).position().top
}, 2000);
}
});
}
function click2center(i) {
let marker = markers[i]
let infowindow = infowindows[i]
if (infowindow.getMap()) {
infowindow.close();
} else {
infowindow.open(map, marker);
map.setCenter(infowindow.position)
}
}
function bookmark(title, address, action) {
$.ajax({
type: "POST",
url: "/add_favorite",
data: {
title: title,
address: address,
action: action
},
success: function (response) {
if (response["result"] == "success") {
get_matjips()
}
}
})
}
</script>
</head>
<body>
<div class="wrap">
<div class="banner">
<div class="d-flex flex-column align-items-center"
style="background-color: rgba(0,0,0,0.5);width: 100%;height: 100%;">
<h1 class="title mt-5 mb-2">스파르타 맛집 지도</h1>
</div>
</div>
<div id="map"></div>
<div class="matjip-list" id="matjip-box">
</div>
</div>
</body>
</html>
Author And Source
이 문제에 관하여(웹개발 플러스 3주차 숙제), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@talysa/웹개발-플러스-3주차-숙제저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)