Python
으로 서버를 구축하는 방법은 크게 Django
를 사용하는 방법과 Flask
모듈을 사용하는 것이다
오늘은 Flask
에 대해 간단히 배워보도록 할텐데 Python
과 VS code
, 그리고 Flask
가 설치되어있다는 가정하에 진행하도록 하겠다
먼저 위 세가지가 설치가 되있다면
from flask import Flask
app = Flask("name") # 이름을 name으로 설정
로 import
해주고 원하는 이름을 설정해준다
그 후에 decorator
로 route
경로를 설정해주고 원하는 function
을 만들어주면 된다
from flask import Flask
app = Flask("name")
@app.route("/")
def home():
return "hello, world!"
app.run()
@(decorator)
는 바로 아래에 있는 function
을 찾아 root
경로로 접속하면 해당 function
을 실행해준다
app.run()
안에 아무것도 넣어주지 않았다면 보통 127.0.0.1:5000
에 들어가면 home
이 실행되어 출력된 것을 볼 수 있을 것이다
해당 경로를 따라 들어가보면
정상적으로 출력된 것을 볼 수 있다
그럼 route("/")
은 무엇인가? 라는 의문이 생길텐데 말 그대로 경로를 지정해주는 것으로
from flask import Flask
app = Flask("name")
@app.route("/contact")
def contact():
return "010-1234-5678, plz contact me !"
app.run()
127.0.0.1/contact
라는 주소에 접속하니 contact
가 실행되어 화면에 출력된 것을 볼 수 있다
사실 굳이 route
와 function
의 이름을 맞출 필요는 없지만 그냥 알기 쉽도록 해놓는 것 뿐이다
from flask import Flask
app = Flask("name")
@app.route("/contact")
def pizza(): # 함수이름을 pizza로 바꿈
return "010-1234-5678, plz contact me !"
app.run()
로 이름을 pizza
로 바꿔도 여전히 잘 동작한다
이렇게 이름을 달리해도 동작하는 이유는 @app.route()
는 바로 아래있는 함수만을 인식하기 때문인데
그래서 아래에 함수가 없으면 SyntaxError
가 발생한다
from flask import Flask
app = Flask("name")
@app.route("/contact")
a = 10
def pizza(): # 함수이름을 pizza로 바꿈
return "010-1234-5678, plz contact me !"
app.run()
그럼 route
를 능동적으로 만들수 있을까? 그러면 우리는 placeholder
를 사용하면 된다
from flask import Flask
app = Flask("name")
@app.route("/<username>") # <>안에 원하는 argument를 넣는다
def pizza(username):
return f"{username}, how are you doing?"
app.run()
127.0.0.1/username
에 접속하면 해당 argument
를 받아서 출력해준다
이렇게 우리는 dynamic urls
을 구현할 수 있게 되었다😎
그렇다면 혹시 placeholder
랑 argument
랑 다른 이름을 사용하면 어떻게 될까?
from flask import Flask
app = Flask("name")
@app.route("/<username>") # <>안에 원하는 argument를 넣는다
def pizza(name):
return f"{name}, how are you doing?"
app.run()
안타깝게도 username
을 argument
로 사용하지 않았다는 TypeError
가 발생한다
이렇게 서버를 구축했다면 우리는 html
을 구축해서 사용자에게 보여줘야 할 것이다
from flask import Flask
app = Flask("name")
@app.route("/<username>") # <>안에 원하는 argument를 넣는다
def pizza(username):
return f"<h1>Hello, {username}!</h1>"
app.run()
으로 <h1>
을 return
하게되면
h1
코드를 볼 수 있을 것이다
근데 이런식으로 짜는 건 너무 불편할 것 같다🤮 그래서 우리는 html
파일을 만들어주자
먼저 folder
를 하나 만들어주고 그안에 html
을 만들어주자
나는 /templates/pizza.html
을 만들기로 하겠다
<!DOCTYPE html>
<html lang="ko">
<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">
<title>Test Flask</title>
</head>
<body>
<h1>Test Flask</h1>
<form>
<input type="text" placeholder="Hello, it is test" required>
<button>Test 😎</button>
</form>
</body>
</html>
이 pizza.html
을 어떻게 유저에게 보낼 수 있을까?
이를 위해서는 flask
의 render_template
를 import
해야한다
from flask import Flask, render_template
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
app.run()
render_template
는 templates
폴더 안에 있는 지정된 html
을 찾을 수 있다
꼭 templates
폴더를 만드는 것을 잊지말길 바란다😏
위 html
에서는 아직 button
을 눌러도 아무런 변화가 없다(사실 refresh가 일어난다)
이를 원하는 방식으로 조금 바꿔보도록 하겠다
먼저 html
을
<!DOCTYPE html>
<html lang="ko">
<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">
<title>Test Flask</title>
</head>
<body>
<h1>Test Flask</h1>
<form action="/report" method="get"> <!-- action, method를 추가해줌 -->
<input type="text" placeholder="Hello, it is test" required name="word"> <!-- name을 추가해줌 -->
<button>Test 😎</button>
</form>
</body>
</html>
조금 수정해주고 input
에 아무거나 입력해준 후
test
버튼을 누르면
당연히 오류가 발생한다😁 하지만 주소창을 잘 살펴보면
내가 입력한 abcdef
에 해당하는 http://localhost:5000/report?word=abcdef
로 연결된 것을 볼 수 있다
action="/report"
를 추가했기 때문에 url
에 /report
가 추가되었다
그러나 ?word=abcdef
는 url
이 아니라 무엇을 넣더라도 사실 변화되는 것은 없다
이를
query argument
라고하며 조금 뒤에 살펴보도록 하자
from flask import Flask, render_template
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
return "this is the report"
app.run()
/report
경로를 만들어주고 아무단어나 입력하고 버튼을 눌러보면
report
함수가 실행되는 것을 볼 수 있다
http://localhost:5000/report
주소 뒤에는 어떠한 것을 넣어도 결과는 변함이 없다
예를들어
http://localhost:5000/report?word=qwkdoqkwdp&whateveriwant=here
등을 넣어도 변함이 없음
하지만 word=
에 있는 단어를 가져오고 싶다면? 이제부터 query argument
에 대해 알아보자
일단 flask
에서 request
를 import
하고
from flask import Flask, render_template, request
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
print(request.args.get('word'))
return "this is the report"
app.run()
word=
에 입력되는 것을 print
해보기로 하자
나는 hello
를 입력하고 button
을 누르자 terminal
에 정상적으로 출력되는 모습을 볼 수 있다
from flask import Flask, render_template, request
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
print(request.args)
return "this is the report"
app.run()
get('word')
를 지워주면 모든 argument
를 가져올 수 있다
hello
를 입력하자 ImmutableMultiDict
이 출력됐다
주소에 http://localhost:5000/report?word=hello&want=whatever
와 같이 &want=whatever
를 추가해보도록 하자
그럼 이번에는 ('want', 'whatever')
가 추가된 것을 볼 수 있다
우리는 이제 &
를 통해 구분하여 수많은 argument
를 받아낼 수 있다는 것을 알게되었다
이게 query arguments
다
이를 응용하면
from flask import Flask, render_template, request
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
word = request.args.get('word')
return f"this is the report. you search {word}"
app.run()
이렇게 사용자가 검색한 내용을 출력할 수도 있다
검색내용을 바꾸고 싶다면 주소를 http://localhost:5000/report?word=asia
와 같이 바꿔보길 바란다
이제 우리는 사용자가 입력한 것을 내가 자유자제로 사용할 수 있게되었다
그럼 data
를 template
로 넘겨보도록 하자
<!DOCTYPE html>
<html lang="en">
<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">
<title>Document</title>
</head>
<body>
<h3>You are looking for {{searchingBy}}</h3>
</body>
</html>
templates
폴더 안에 report.html
을 만들고
from flask import Flask, render_template, request
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
word = request.args.get('word')
return render_template("report.html", searchingBy=word)
app.run()
render_template
안에 해당 argument
를 넣어주면 된다
searchingBy
는 다른 이름으로 바꿀 수 있으니 html
과 맞춰주는 것만 잊지말도록 하자
어떻게 실시간으로 이런일이 벌어지는가?
flask
가 argument
들을 기억한 상태로 html
을 살펴보고 {{}}(double curly brackets)
안에 있는 argument
들에게 각각에 맞는 값들을 넣어주는 것이며 이를 rendering
이라고 한다
만약 사용자가 아무것도 입력하지 않은채 버튼을 눌러버리면 어떻게 될까?
원래는 빈공간일때 None
으로 반환해 주기때문에 아마 You are looking for None
이 보일 것이다
(사실 이렇게 된 사람들은 <input>
의 attribute
에 required
을 넣어주지 않은 사람들에 한함)
어찌됐든 우리는 None
을 반환하는 것을 원하지 않고, 소문자와 대문자는 엄연히 다른 것이므로 이도 걸러주기위해
from flask import Flask, render_template, request, redirect
app = Flask("name")
@app.route("/")
def home():
return render_template("pizza.html")
@app.route("/report")
def report():
word = request.args.get('word')
if word:
word = word.lower()
else:
return redirect("/")
return render_template("report.html", searchingBy=word)
app.run()
if
문을 사용해 lower()
와 import redirect
를 통해 해결해줬다