라우팅
간단하게 말하면, 어떤 요청을 어떤 함수가 응답할 것인가 연결해주는 작업
자세하게 말하면, 클라이언트로부터 요청받은 URL과 뷰를 매칭시키는 것을 말합니다.
Flask에서는 파이썬의 데코레이터(decorator)문법을 이용하여 URL을 처리하고 결론적으로 라우팅을 설정합니다.
여기서 데코레이터(decorator)란
함수에 반복적인 기능과 역할을 할 수 있도록 만들어주는(decoration) 기능으로 함수를 인자로 받아 사용합니다.
함수 내부의 로직을 수정하지않고, 기능을 추가하거나 수정 하고싶을 때 사용합니다.
데코레이터는 아래 코드에서 @app.route("/") 에 대한 것입니다.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return 'rendering result'
전체적으로 봤을 때 index() 함수를 감싼 모습입니다.
from flask import Flask
flask라는 패키지에서 Flask 모듈을 import해줘서 플라스크를 사용할 수 있게 설정한다.
app = Flask(__name__)
Flask 인스턴스를 생성한 것이다. python에서 __name__은 모듈의 이름을 뜻합니다.
모듈로 파일을 실행시킬 경우에는 특정 코드가 실행되지 않도록 하는 기능으로 주로 사용
해당부분에 대해 자세하게 이해하고 싶다면 아래링크를 참고해주세요.
@
옆에 쓰인 함수가 그 밑에 정의된 함수를 인자로 받겠다는 것을 의미합니다.
route()
()안의 주소에 접속하면 그 바로 아랫줄에 있는 함수를 호출하는 flask의 decorator로 함수를 URL에 바인딩합니다.
'/'
'/' 라는 URL 은 index() 함수와 연결된 상태로클라이언트가 '/'라는 URL을 통해 request를 보내면
플라스크는 '/'라는 URL request이 들어오게 되고 index()함수를 실행하게됩니다.
변수 규칙
Flask는 URL에 변수를 할당하여 동적으로 만들 수 있습니다.
그 방법은 원하는 변수이름에 "<>"를 붙히면 됩니다.
<variable_name>을 사용해 URL에 변수를 추가할 수 있습니다.
그렇게 되면 함수는 <variable_name>을 키워드 인수로 받아들입니다.
from flask import Flask
app = Flask(__name__)
@app.route('/user/<username>')
def show_user_profile(username):
return f'User is... {username}'
@app.route('/post/<int:intID>')
def show_a(intID):
return 'int is... %d' % intID
@app.route('/post2/<string:stringID>')
def show_b(stringID):
return 'string is... %s' % stringID
@app.route('/path/<path:subpath>')
def show_c(subpath):
return 'Subpath is... %s' % subpath
@app.route('/path2/<uuid:uuID>')
def show_d(uuID):
return 'uuid is... %s' % uuID
컨버터 유형에 대한 예제코드 입니다.
위와 같이 선택적으로 변환기를 사용하여 같은 인수 유형을 지정 할 수 있습니다.
고유한URLs / Redirection 동작 - 후행 슬래시
from flask import Flask
app = Flask(__name__)
@app.route('/projects/')
def slash():
return 'The project page'
@app.route('/about')
def noslash():
return 'The about page'
route()안의 마지막 부분에 슬래시(/) 가 있을때와 없을때의 차이가 있습니다.
슬래시(/)가 있을 경우 - 후행 슬래시가 있든없든 URL에 엑세스하면
Flask가 후행 슬래시가 있는 표준 URL로 Redirection(이동)합니다.
슬래시(/)가 없는 경우 - 슬래시가 있는 URL에 엑세스하면 'page 404' 오류 발생합니다
리소스에 대한 URL에 대한 URL을 고유하게 유지하여
검색 엔진이 동일한 페이지를 두 번 인덱싱 하는 것을 피할 수 있습니다.
URL Building
특정 함수를 위해서 URL을 동적으로 만드는데 유용한 url_for() 함수가 있습니다.
from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login ...'
@app.route('/hello/<guest>')
def hello_user(guest):
return 'hello %s' % guest
@app.route('/user/<username>')
def profile(username):
if username == 'a':
return redirect(url_for('index'))
elif username == 'login':
return redirect(url_for('login'))
else:
return redirect(url_for('hello_user',guest = username))
이 함수의 첫 번째 인자는 특정 함수의 이름이고 나머지부분은 키워드 인자들을 받습니다.
자세하게 설명하면 profile() 함수는 username 을 URL에서 변수로 받습니다.
만약 username이 'a' 이면 url_for 함수를 사용해 index() 함수를 리다이렉트를 합니다.
또 만약 username이 'login' 이면 url_for 함수를 사용해 login() 함수를 리다이렉트를 합니다.
두가지 경우가 모두 아니라면 profile() 함수는 username을 guest이름으로 간주하고
profile() 함수와 guest는 해당 username으로써 리다이렉트 합니다.
HTTP Methods
HTTP는 웹 어플리케이션에서 사용하는 프로토콜로, url 접근에 대해 몇 가지 다른 방식을 제공하고 있습니다.
기본적으로는 GET방식으로 제공되지만, route()데코레이터에 methods 인자를 제공하면 다른 방식으로 변경할 수 있습니다.
GET방식
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
데이터를 추가하는 로직을 보면 request.method가 POST방식인지 아닌지 확인할 수 있습니다.(methods=['GET', 'POST'])
또는 request.method를 통해서 flask는 요청한 것이 GET인지 POST인지 구별 할 수 있는데
request.args 를 통해 데이터를 가져올 수도 있고(GET 방식)
request.form 을 이용해서 전송한 데이터를 가져올 수 있다.(POST방식)
단, 그러기 전에 request(웹브라우저가 웹서버한테 전송한 여러가지 정보,상태) 라고하는 모듈을 import해야 합니다.
from flask import request
전체적인 이해를 돕기위한 코드입니다.
아래에 각 코드에 관한 설명이 포함되어있습니다.
from flask import Flask, redirect, url_for, request
app = Flask(__name__)
Platforms = [
{'myName': 'KIM' },
{'myName': 'RIN'},
{'myName': 'AHN'}
]
def explan():
liTags =''
for Platform in Platforms:
liTags += f'<li>{Platform["myName"]}</a></li>'
return liTags
def templete(context,name):
return f'''<html>
<body>
{context}
<form action = "/login" method = "post">
<p>Enter Name: {name}</p>
<p><input type = "text" name = "myName" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>'''
@app.route('/')
def index():
return templete(explan(),None)
@app.route('/success/<name>')
def success(name):
return templete(explan(),name)
@app.route('/login', methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['myName']
newPlatform = {'myName':user}
Platforms.append(newPlatform)
print(Platforms)
return redirect(url_for('success', name = user))
elif request.method == 'GET':
user = request.args.get('myName')
return redirect(url_for('success', name = user))
if __name__ == '__main__':
app.run(debug = True)
Platforms = [
{'myName': 'KIM' },
{'myName': 'RIN'},
{'myName': 'AHN'}
]
딕셔너리와 리스트로 표현하여 데이터베이스의 구조와 비슷한 형태로 만들었습니다.
def templete(context,name):
return f'''<html>
<body>
{context}
<form action = "/login" method = "post">
<p>Enter Name: {name}</p>
<p><input type = "text" name = "myName" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>'''
form 태그 내부에 text input과 submit input이 있습니다. text의 input는 name으로 myName을 가집니다.
Flask의 웹 애플리케이션에서는 request.form[‘myName’]으로 접근하게 됩니다.
그러므르 submit의 input은 value로 submit을 가집니다.
def explan():
liTags =''
for Platform in Platforms:
liTags += f'<li>{Platform["myName"]}</a></li>'
return liTags
read 구현에 도움을 줄만한 코드입니다.
원하는 'myName'이 url에 들어갔을 때 데이터들을 순서대로 불러오는 기능을 위함입니다.
@app.route('/')
def index():
return templete(explan(),None)
홈페이지 화면을 나타내는 코드입니다.
아래 코드와 같이 살펴보면 'templete(context,name)'에서 templete함수의 인자가 또 다른 함수와 name 값인데
처음 홈페이지 화면을 들어갔을 땐 입력 되어있는 name값이 없기 때문에 index함수의 name 리턴값을 'None' 으로 설정했습니다.
def templete(context,name):
return f'''<html>
<body>
{context}
<form action = "/login" method = "post">
<p>Enter Name: {name}</p>
<p><input type = "text" name = "myName" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>'''
@app.route('/success/<name>')
def success(name):
return templete(explan(),name)
@app.route('/login', methods = ['POST', 'GET'])
def login():
if request.method == 'POST':
user = request.form['myName']
newPlatform = {'myName':user}
Platforms.append(newPlatform)
print(Platforms)
return redirect(url_for('success', name = user))
POST를 이용한 방식입니다.
서버는 POST 메소드로 데이터를 전달받습니다. form 데이터에서 얻은 ‘myName’ 매개변수의 값은
user = request.form['myName'] 에서 얻어집니다.
url_for() API를 사용해서 동적으로 url을 생성하고, redirect합니다.
‘/success’ URL에 변수 부분(<name>)으로 전달됩니다.
브라우저는 전달받은 변수 부분을 Enter Name: 옆에 보여줍니다.
첫 실행화면 입니다.
입력하고 싶은 'name'을 입력하고 Submit을 누릅니다.
보시는 것과 같이 전달받은 변수 부분이 보이고 데이터가 한가지 더 추가된 걸 확인 할 수 있습니다.
def templete(context,name):
return f'''<html>
<body>
{context}
<form action = "/login" method = "get">
<p>Enter Name: {name}</p>
<p><input type = "text" name = "myName" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>'''
이번에는 HTTP 프로토콜의 GET방식을 사용해보겠습니다.
methhod = "post" 에서 methhod = "get" 으로 수정합니다.
@app.route('/login', methods = ['POST', 'GET'])
def login():
elif request.method == 'GET':
user = request.args.get('myName')
return redirect(url_for('success', name = user))
GET 메소드에 의해서 서버로 데이터가 전달됩니다. ‘myName’ 매개변수의 값은
user = request.args.get(‘myName’) 에서 얻어집니다.
args는 form 매개변수와 그에 상응하는 값의 쌍을 포함하는 dictionary 객체입니다.
POST로 전달한 데이터가 아니므로 args로 접근해야 합니다.
‘myName’ 매개변수에 상응하는 값은 앞에서 처럼 ‘/success’ URL로 전달됩니다.
이렇게 데이터가 추가가 되지 않는 것을 보아, post와는 다르게 데이터 조회(Read)에만 사용된다는 것을 알 수 있습니다.
여기까지 HTTP Methods / URL Building / 데코레이터 / 변수 규칙 / 후행 슬래시에 관해 모두 알아봤습니다!
'flask' 카테고리의 다른 글
Flask - 테스트 코드 / 관리자 페이지 / 카테고리, 게시물 (0) | 2022.08.10 |
---|---|
Flask - 회원가입/로그인/로그아웃 처리 [블로그 웹 애플리케이션 개발] (0) | 2022.07.27 |
Flask - 라이브러리 설치부터 정적 파일 다루기까지 ( Blueprint / jinja template engine / render_template() ) (0) | 2022.07.11 |
Flask - python으로 쉽게 데이터베이스 다루기 (0) | 2022.07.07 |
FLask 개발 환경의 첫 단계 (0) | 2022.07.03 |