강의를 보고 따라해도 수 차례 오류가 있었지만 어찌저찌 잘 돌아가는 나만의 웹사이트가 완성되었다 😶🌫️

우선 웹 사이트의 메인화면에 들어가면 간단하게 사용자의 이름을 입력 받고 싶어서 JavaScript 의 Prompt 를 사용했다.

그렇게 입력 받은 값을 textContent 로
문자열과 합쳐주면 되는 간단한 스크립트 작업이다.
navbar 에 있는 Music 을 누르면 Music.html 화면으로 이동할 수 있다.
href = " {{ url_for('music')}}

이제 Flask와 Python 코드를 이용하여 만든 노래 공유 사이트 화면으로 이동했다.

좋아하는 노래의 이미지 주소 복사를 하고
modal 창에 입력해주면 된다.

입력을 완료해주고 Submit 을 누르면
데이터가 연동된 python 파일로 넘어오게 된다.

주소창으로도 music/윤성 과 같이 데이터를 입력 받아
신청자의 이름 별로도 확인이 가능하다.
코드는 이러하다
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary" data-bs-theme="dark">
<div class="ms-3">
<img src="">
</div>
<div class="container-fluid">
<a class="navbar-brand" href="#"></a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item"> <!-- 클릭하면 다른 페이지로 이동시켜주는 작업-->
<a class="nav-link active" aria-current="page" href="{{ url_for('home')}}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('music')}}">Music</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">artist</a>
</li>
<li class="nav-item">
<a class="nav-link disabled" aria-disabled="true">.</a>
</li>
</ul>
</div>
</div>
<div class="weather">
<img id="weather-icon">
<p id="weather-msg"></p>
</div>
</nav>
<div class="container">
<div class="greeting">
<h1 id="greeting-text"></h1> <!-- app.py 에 있는 데이터를 넘겨주는 작업 -->
<h1 id="current-time"></h1>
</div>
<div class="motto">
<h3>{{ data.motto }}</h3>
<h2>{{ data.daily }}</h2>
</div>
</div>
<div class="footer">
<p id="quotoAuthor"></p>
<p id="quoto_Profile"></p>
</div>
<script>
var userInput = prompt("이름을 입력하세요 : ");
var userName = userInput || "Guest";
var greetingText = document.getElementById("greeting-text");
greetingText.textContent = "안녕하세요" + " " + userName + "님";
function disPlayCurrentTime() {
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
var seconds = currentTime.getSeconds();
// AM 또는 PM 을 설정
var meridiem = hours >= 12 ? "PM" : "AM"
// 시간이 12를 넘어가면 12로 나눠서 표시
hours = hours > 12 ? hours - 12 : hours;
// 0 을 붙여 한 자리 숫자를 두 자리로 만들기
hours = addZero(hours);
minutes = addZero(minutes);
seconds = addZero(seconds);
// 시간을 HTML 요소에 표시
var timeString = hours + ":" + minutes + ":" + seconds + "" + meridiem;
document.getElementById("current-time").innerHTML = timeString;
}
function addZero(number) {
return number < 10 ? "0" + number : number;
}
// 1초마다 시간을 업데이트
setInterval(disPlayCurrentTime, 1000);
let quoto_url = "https://korean-advice-open-api.vercel.app/api/advice"
fetch(quoto_url)
.then(res => res.json())
.then(data => {
let message = data['message']
let author = data['author']
let authorMsg = `${message}`
let authorProfile = `${author}`
$('#quotoAuthor').text(message)
$('#quoto_Profile').text(authorProfile)
})
// weather script code
let weather_url = "http://spartacodingclub.shop/sparta_api/weather/seoul";
fetch(weather_url)
.then(res => res.json())
.then(data => {
let temp = data['temp']
let icon_url = data['icon']
let message = `${temp}°C`
$('#weather-msg').text(message)
$('#weather-icon').attr('src', icon_url)
})
</script>
<!-- body 태그 안에 넣는 script link -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
<!-- body 태그 안에 넣는 Popper 와 js script -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
crossorigin="anonymous"></script>
</body>
</html>
displayCurrentTime 스크립트는 조금 헤맸던것 같다.
변수,함수 선언을 하고 할당을 하고 무슨 소리야 ? 매개 변수? 무슨 소리지
weather_url 과 quoto_url 은 fetch 기능으로 해당 웹 사이트의 API 를 가져와 사용하였다.
두번째 url 같은 경우는 강의에서 얻은 API 가 아니라 구글링하여 깃헙으로 알게되었다.
아, 이런 느낌이군. add 나 commit 같은건 잘 모르겠지만 이런거라는건 알겠어.
계속해보자면
Music.html 는 데이터를 html 에 반영해주는 코드만
전반적으로 index.html 과 뼈대는 같고 중요한건 이것을
{for song in data}로 반복하여 화면에 나타나게 해준다는 것이다.
정적 웹사이트가 목표가 아니였으니까 !
<div class="row row-cols-1 row-cols-md-4 g-4 mx-auto w-75 pb-5">
<!-- 하나씩 꺼내온 데이터를 song이라고 네이밍--> {% for song in data %} <!-- ffor로 for문 작성, app.py에서 data라는 이름으로 데이터를 보냄 -->
<div class="col">
<div class="card h-100">
<img src="{{song.image_url}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{song.title}}</h5>
<p class="card-text">{{song.artist}}</p>
<p class="card-text">{{song.username}}</p>
</div>
</div>
</div>
{% endfor %}
혼란의 app.py 파일 코드는 이러하다.
DB란 무엇이고 이걸 어떻게 받아오며 받아온 데이터를 어떻게 반영하는지
Flask 와 render_template, request 정도만 존재를 알겠다.
노래 신청으로 받아온 DB는 SQLAlchemy 에 잘 보관되어 있다.
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__) # import 는 자주 해보면 감이 잡히겠지 싶다.
# ( 아직 뭘 넣어야 하는지 모르겠다 )
# 11~ 32줄 DB 기본 코드
import os
from flask_sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] =\
'sqlite:///' + os.path.join(basedir, 'database.db')
db = SQLAlchemy(app)
class Song(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100), nullable=False)
artist = db.Column(db.String(100), nullable=False)
title = db.Column(db.String(100), nullable=False)
image_url = db.Column(db.String(10000), nullable=False)
def __repr__(self):
return f'{self.username} {self.title} 추천 by {self.username}'
with app.app_context():
db.create_all()
@app.route("/")
def home():
#name = "윤성"
motto = "버티면 되는거야"
daily = "오늘 하루도 화이팅하자!"
# 목표 : 처음 사이트 접속하면 alert창으로 사용자의 이름 데이터를 입력 받고 화면에 출력
context = {
"name" : name,
"motto" : motto,
"daily" : daily,
}
return render_template('index.html', data=context)
# prompt 함수로 사용자의 데이터를 입력 받아오는 코드
# @app.route('/greet', methods=['POST'])
# def greet():
# user_name = request.form['user_name']
# return render_template('index.html', user_name=user_name)
@app.route("/music")
def music():
song_list = Song.query.all()
return render_template('music.html', data=song_list)
@app.route("/music/<username>/") # <> 로 감싸주면 변수처럼 가져와서 데이터화 사용 가능
def render_music_filter(username): # 겹치면 안되므로 music의 이름을 render_music_filter로 변경
filter_list = Song.query.filter_by(username=username).all()
song_list = Song.query.all() # = 뒤에 있는 username은 50줄에서 받아온 username 이다.
return render_template('music.html', data=song_list) #데이터를 가져오는 코드를 작성
#data= ""
#
@app.route("/music/create/")
def music_create():
# form에서 보낸 데이터 받아오기
# receive는 단순 변수의 이름
# html 에서 명찰을 달아준 name=""을 가져온다
# request.args.get 을 사용하려면 상단에 import 시켜줘야 하는거 명시
username_receive = request.args.get("username")
title_receive = request.args.get("title")
artist_receive = request.args.get("artist")
image_receive = request.args.get("image_url")
# 데이터를 DB에 저장하는 작업
song = Song(username=username_receive,title=title_receive,artist=artist_receive,image_url=image_receive)
db.session.add(song) # 데이터 베이스에 추가 (저장)
db.session.commit() # 데이터를 세이브 (완전 확정)
# return render_template('music.html')
return redirect(url_for('render_music_filter',username=username_receive))
# redirect = 페이지 이동 -> render_music_filter , 데이터를 넘겨줄때 추천자의 이름도 같이 넘겨줌
# 음악 등록 후 자동으로 추천인의 페이지로 이동
if __name__ == "__main__":
app.run(debug=True)

python anywhere 를 이용하여 실시간 서버도 구현하였다 !
같은 팀원분들에게 음악 추가 요청을 부탁드렸는데,
흔쾌히 해주셨다 👏😺
그 결과 팀원분들이 입력한 음악들이 성공적으로 웹 사이트에 반영되는걸 확인