🦄 사전 스터디 4주차 강의회고록
4일차, 4주차 완강 목표!🙌
오늘은 가장 중요한 서버를 가동하고, 풀스택 미니 프로젝트를 2개나 진행하는 4주차 이다!
힘들겠지만 꼭! 오늘 안에 완강하도록 하자!
✨02/14 : 목표 : 사전스터디 4주차 완강
📒강의 노트 정리
✨02 Flask 시작하기 - 서버만들기
- Flask : 서버를 구동시켜주는 파이썬 프레임워크
1. 해당 파일 경로로 이동, app.py 생성 =>통상적으로 python의 기본파일(index같은) 이름은 app.py다.
2. 가상환경 venv 생성 및 활성화 (라이브러리, 패키지를 담아놓는 폴더) => 인터프리터 3.8.6('venv')로 변경 후 터미널 새로 키고 ('venv') 인지 확인
$ python -m venv venv
3. Flask 패키지 설치
pip install flask
4. ✨Flask 시작 코드 => F5 서버실행 => 방화벽 엑세스허용
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
5. 서버 실행된 것 확인 => 브라우저 http://localhost:5000/ 주소로 이동
- 내 컴퓨터(인터넷 망에 접속된)에서 내가 만든 웹 서비스에 접속한 것, 나만 볼 수 있음, 몇가지 더 설정 하면 내 와이파이 인터넷망에 접속한 모든 사람이 볼 수 있음
- 내 웹 서비스의 http://localhost:5000서버, / api창구
+ 네트워크, 인터넷 망과 서버와의 관계에 대해 더 알아보기
1) mypage 만들기
@app.route('/mypage')
def mypage():
return 'This is my mypage!'
- /mypage경로로 이동하면 mypage가 생성됨
=> ✨ 내 http://localhost:5000 로컬 서버의, /mypage api창구에서,
flask 서버가 돌면서 index.html 파일을 응답해 주고, 브라우저는 응답받은 html, css, js를 그려준다.
2) 버튼 만들기(새로고침 시 변경된 내용 반영)
@app.route('/mypage')
def mypage():
return '<button>버튼입니다!</button>'
04 Flask 시작하기 - HTML 파일 추가
1. HTML 파일 Flask에 연결하기
1) templates 파일 생성 후 index.html 생성
2) Flask내장함수 render_template import
from flask import Flask, render_template #render_template Flask내장함수 import
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html') #render_template('html문서')
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
- 해당 경로에 html파일이 연결됨
✨05 Flask 시작하기 - 본격 API 만들기
- 프론트와 백엔드의 통신 방법
- HTTP 라는 통신 규약에 따라, 클라이언트는 요청할 때 HTTP request method(요청 메소드: get, post 등등)를 통해, 어 떤 요청 종류인지 응답하는 서버 쪽에 정보를 알려준다.
1. GET , POST
1) GET 요청
- 통상적으로 데이터 조회(Read)를 요청할 때, 사용한다. 브라우저 URL에 입력가능하고 눈에 보임
예) 영화 목록 조회 → 데이터 전달 : URL 뒤에 물음표?를 붙여 ?key=value로 전달
2) POST 요청
통상적으로 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때 사용한다. 우리 눈에 안보이며 컴퓨터끼리만 알아볼 수 있는 방식
예) 회원가입, 회원탈퇴, 비밀번호 수정 → 데이터 전달 : 바로 보이지 않는 HTML
2. GET 요청해보기
1) 프론트 => GET 요청, 응답받는 코드(Fetch)
fetch("/test")
.then((res) => res.json())
.then((data) => {
console.log(data);
});
2) 백엔드=> GET요청 응답API 기본코드
@app.route('/test', methods=['GET'])
def test_get():
title_receive = request.args.get('title_give')
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
- ✨전체 코드 : app.py에 requests과 jsonify import
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
#GET '/test' 창구로 GET요청이 들어온다.
@app.route('/test', methods=['GET'])
def test_get():
title_receive = request.args.get('title_give') #'title_give'라는 데이터가 들어오면
print(title_receive) # 확인해보고
return jsonify({'result':'success', 'msg': '이 요청은 GET!'}) #프론트에게 다음과같은 데이터를 내려준다
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
=> test 창구로 GET요청이 들어온다. => 만약 'title_give'라는 데이터가 들어오면
=> {'result':'success', 'msg': '이 요청은 GET!'} 프론트에게 다음과같은 JSON 데이터를 내려준다
- 프론트에서 결과 확인
2. POST 요청해보기
1) 프론트 => POST 요청, 응답받는 코드(Fetch)
let formData = new FormData();
formData.append("title_give", "블랙팬서");
fetch("/test", { method: "POST", body: formData }) //POST는 요구하는 정보를 보내줘야 함
.then((res) => res.json())
.then((data) => {
console.log(data);
});
2) 백엔드=> POST요청 응답API 기본코드
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
- ✨전체 코드 : app.py에 requests과 jsonify import
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
=> 프론트에서 특정 정보로 request 요청 => 백엔드에서 받아서 확인 후 응답 => 프론트에서 받아서 출력
- 프론트에서 결과 확인
06 화성땅 공동구매 프로젝트
07 스파르타피디아 프로젝트
08 숙제 : 별점 추가하기
1. 프론트
function listing() {
$("#cards-box").empty();
fetch("/movie")
.then((res) => res.json())
.then((data) => {
let movies = data["posts"];
movies.forEach((post) => {
let image = post["image"];
let title = post["title"];
let desc = post["desc"];
let comment = post["comment"];
//추가
let star = post["star"];
let star_repeat = "⭐".repeat(star);
let temp_html = `
<div class="col">
<div class="card h-100">
<img
src=${image}
class="card-img-top"
/>
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">${desc}</p>
//추가
<p>${star_repeat}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>
`;
$("#cards-box").append(temp_html);
});
});
}
function posting() {
let url = $("#url").val();
let comment = $("#comment").val();
//추가
let star = $("#star").val();
let formData = new FormData();
formData.append("url_give", url);
formData.append("comment_give", comment);
//추가
formData.append("star_give", star);
fetch("/movie", { method: "POST", body: formData })
.then((res) => res.json())
.then((data) => {
console.log(data);
alert(data["msg"]);
});
window.location.reload();
}
2.백엔드
@app.route("/movie", methods=["POST"])
def movie_post():
url_receive = request.form['url_give']
comment_receive = request.form['comment_give']
#추가
star_receive = request.form['star_give']
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url_receive,headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
ogimage = soup.select_one('meta[property="og:image"]')
ogtitle = soup.select_one('meta[property="og:title"]')
ogdesc = soup.select_one('meta[property="og:description"]')
image = ogimage['content']
title = ogtitle['content']
desc = ogdesc['content']
doc = {
'image': image,
'title' : title,
'desc' : desc,
'comment' : comment_receive,
#추가
'star' : star_receive,
}
post = db.posts.insert_one(doc)
print(post)
return jsonify({'msg':'포스팅 완료!'})
@app.route("/movie", methods=["GET"])
def movie_get():
posts =list(db.posts.find({},{'_id': False}))
print(posts)
return jsonify({'posts':posts})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
✅ 느낀점
4일차도 무사히 4주차를 완강했다!🙌
내 로컬 서버를 연동하여 실제로 동작하는 웹 서비스를 무려 2개나 완성시킬 수 있었다!
비록 귀여운 수준이지만 프론트 + 백엔드 + 서버까지 연동되는 풀스택 미니 프로젝트를 내가 만들었다는 사실이 너무 뿌듯하다.
다만 오늘 강의는 아무래도 처음 서버를 다루다보니 굉장히 예상치 못한 에러를 많이 만나게 되었다. 덕분에 시간을 굉장히 많이 쏟은 프로젝트들이었지만 혼자 실제로 동작하는 웹 서비스를 하루만에 두 개나 만들었다는게 너무나 뿌듯하고 설렜다...🤭
빨리 다음 주차를 배워서 배포까지 진행하고 싶다! 너무 많은 내용을 한 번에 배워서 잊어버릴까 걱정되긴 하지만.. 다음 주차에서도 프로젝트를 또 진행한다고 하니 반복학습이 될 것 같아 다행이다! 계속해서 연습, 반복 해야겠다.🙌
✖️보완할 점, 아쉬운 점
더 공부하고 싶은 부분 : 네트워크, 인터넷 망과 서버와의 관계에 대해 더 알아보기, 화성땅 공동구매 프로젝트에 삭제 기능 넣어보기
프로젝트들은 뼈대만 잡아 놓고 강의를 보기 전에 혼자 완성했다! 하지만 500에러.. Fetch에러.. 등등
각종 에러들 때문에 멘붕에 멘붕의 연속이었다....ㅠㅠ 알고보니 코드가 잘못된 게 아니라
❗서버가 꺼져있다던지.. 서버를 새로고침 하지 않아 그 전 코드로 계속 실행하고 있었던 것이었다...
프론트에 익숙하다 보니 라이브 서버같이 자동적용이 안된다는 것을 잊고 있었다..
...후...... 이제라도 알았으니 다행이다! 다음부턴 꼭!! 반드시 서버가 실행되고 있는지 먼저 확인하고,
수정할 때 마다 새로고침을 잊지 말아야겠다!
❗mongoClient에 내 db 주소를 넣을 때, <password>부분은 꼭 변경해 줘야한다! 잊지말기!
❗가독성 좋은 코드를 작성하기 위해서는 복잡한 로직보다는 깔끔하게 한번 더 변수에 담아서 정리하는 것이 좋다는 것을 깨닳았다.
❗import 시에는 한번에 다 줄세우지 않고 flask는 flask끼리, db는 db끼리 등등 관련된 애들끼리 묶어놓는게 가독성에 훨씬 좋은 것 같다.
'항해99 > 사전 스터디' 카테고리의 다른 글
[항해99] 사전스터디 - 5주차 강의회고록 (0) | 2023.02.15 |
---|---|
[항해99] 사전스터디 - 3주차 강의회고록 (0) | 2023.02.13 |
[항해99] 사전스터디 - 2주차 강의회고록 (0) | 2023.02.12 |
[항해99] 사전스터디 - 1주차 강의회고록 (0) | 2023.02.11 |