Flask(4)

majaeh43ยท2021๋…„ 12์›” 8์ผ
1

Eager to learn Flask ๐Ÿ”ฅ

๋ชฉ๋ก ๋ณด๊ธฐ
4/7

์ฟ ํ‚ค์™€ ์„ธ์…˜

๐Ÿค ์ฟ ํ‚ค

  • ์ •๋ณด๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์—†๋Š” Connectionless, Stateless์˜ ์„ฑ๊ฒฉ์„ ๊ฐ€์ง„ HTTP์˜ ๋‹จ์ ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ฟ ํ‚ค๋ผ๋Š” ๊ฐœ๋…์ด ๋„์ž…!
  • ์›น ์„œ๋ฒ„๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ง€์‹œํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ๋กœ์ปฌ ์ปดํ“จํ„ฐ์— ํŒŒ์ผ ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๋Š” ์ž‘์€ ๊ธฐ๋ก ์ •๋ณด ํŒŒ์ผ.
  • ํŒŒ์ผ์— ๋‹ด๊ธด ์ •๋ณด๋Š” ์ธํ„ฐ๋„ท ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ™์€ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๋งˆ๋‹ค ์ฝํžˆ๊ณ  ์ˆ˜์‹œ๋กœ ์ƒˆ๋กœ์šด ์ •๋ณด๋กœ ๋ฐ”๋€” ์ˆ˜ ์žˆ์Œ.
  • ์›น์„œ๋ฒ„์—์„œ response ํ•  ๋•Œ ํ—ค๋”์— ์ฟ ํ‚ค๋ฅผ ๋‹ด์•„์„œ ๋ณด๋‚ด์ค€๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋จ!

๐ŸŒˆ ์ฟ ํ‚ค์˜ ๋™์ž‘ ์ˆœ์„œ

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ๋‹ค. (์‚ฌ์šฉ์ž๊ฐ€ ์›น์‚ฌ์ดํŠธ ์ ‘๊ทผ)
  2. ์›น ์„œ๋ฒ„๋Š” ์ฟ ํ‚ค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  3. ์ƒ์„ฑํ•œ ์ฟ ํ‚ค์— ์ •๋ณด๋ฅผ ๋‹ด์•„ HTTP ํ™”๋ฉด์„ ๋Œ๋ ค์ค„ ๋•Œ,
  4. ๊ฐ™์ด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋Œ๋ ค์ค€๋‹ค.
  5. ๋„˜๊ฒจ ๋ฐ›์€ ์ฟ ํ‚ค๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๊ฐ€(๋กœ์ปฌ PC์— ์ €์žฅ)
  6. ๋‹ค์‹œ ์„œ๋ฒ„์— ์š”์ฒญํ•  ๋•Œ ์š”์ฒญ๊ณผ ํ•จ๊ป˜ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•œ๋‹ค.
  7. ๋™์ผ ์‚ฌ์ดํŠธ ์žฌ๋ฐฉ๋ฌธ์‹œ ํด๋ผ์ด์–ธํŠธ์˜ PC์— ํ•ด๋‹น ์ฟ ํ‚ค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ,
    ์š”์ฒญ ํŽ˜์ด์ง€์™€ ํ•จ๊ป˜ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•œ๋‹ค.
  • ์ฟ ํ‚ค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋งค ํ—ค๋”(Http Header)์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋ณด๋‚ด๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋‹นํ•œ traffic์„ ๋ฐœ์ƒ.
  • ๊ฒฐ์ œ์ •๋ณด๋“ฑ์„ ์ฟ ํ‚ค์— ์ €์žฅํ•˜์˜€์„๋•Œ ์ฟ ํ‚ค๊ฐ€ ์œ ์ถœ๋˜๋ฉด ๋ณด์•ˆ์— ๋Œ€ํ•œ ๋ฌธ์ œ์ ๋„ ๋ฐœ์ƒ๊ฐ€๋Šฅ...!

๐Ÿค ์„ธ์…˜

  • ์ฟ ํ‚ค์˜ ํŠธ๋ž˜ํ”ฝ ๋ฌธ์ œ์™€ ์ฟ ํ‚ค๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ณด์•ˆ์  ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅ.

  • ์ผ์ • ์‹œ๊ฐ„๋™์•ˆ ๊ฐ™์€ ์‚ฌ์šฉ์ž(๋ธŒ๋ผ์šฐ์ €)๋กœ๋ถ€ํ„ฐ ๋“ค์–ด์˜ค๋Š” ์ผ๋ จ์˜ ์š”๊ตฌ๋ฅผ ํ•˜๋‚˜์˜ ์ƒํƒœ๋กœ ๋ณด๊ณ , ๊ทธ ์ƒํƒœ๋ฅผ ์ผ์ •ํ•˜๊ฒŒ ์œ ์ง€์‹œํ‚ค๋Š” ๊ธฐ์ˆ . (์—ฌ๊ธฐ์„œ ์ผ์ • ์‹œ๊ฐ„์€ ๋ฐฉ๋ฌธ์ž๊ฐ€ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ์›น ์„œ๋ฒ„์— ์ ‘์†ํ•œ ์‹œ์ ์œผ๋กœ๋ถ€ํ„ฐ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•˜์—ฌ ์—ฐ๊ฒฐ์„ ๋๋‚ด๋Š” ์‹œ์ ) ์ฆ‰, ๋ฐฉ๋ฌธ์ž๊ฐ€ ์›น ์„œ๋ฒ„์— ์ ‘์†ํ•ด ์žˆ๋Š” ์ƒํƒœ๋ฅผ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ณด๊ณ  ๊ทธ๊ฒƒ์„ ์„ธ์…˜์ด๋ผ๊ณ  ํ•จ.

  • ์›น ์„œ๋ฒ„์— ์›น ์ปจํ…Œ์ด๋„ˆ์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค. ์›น ์„œ๋ฒ„์˜ ์ €์žฅ๋˜๋Š” ์ฟ ํ‚ค(=์„ธ์…˜ ์ฟ ํ‚ค). ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋‹ซ๊ฑฐ๋‚˜, ์„œ๋ฒ„์—์„œ ์„ธ์…˜์„ ์‚ญ์ œํ–ˆ์„๋•Œ๋งŒ ์‚ญ์ œ๊ฐ€ ๋˜๋ฏ€๋กœ, ์ฟ ํ‚ค๋ณด๋‹ค ๋น„๊ต์  ๋ณด์•ˆ์ด ์ข‹๋‹ค. ์ €์žฅ ๋ฐ์ดํ„ฐ์— ์ œํ•œ์ด ์—†๋‹ค.(์„œ๋ฒ„ ์šฉ๋Ÿ‰์ด ํ—ˆ์šฉํ•˜๋Š” ํ•œ...) ๊ฐ ํด๋ผ์ด์–ธํŠธ ๊ณ ์œ  Session ID๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค. Session ID๋กœ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ๊ฐ ํด๋ผ์ด์–ธํŠธ ์š”๊ตฌ์— ๋งž๋Š” ์„œ๋น„์Šค ์ œ๊ณต.

๐ŸŒˆ ์„ธ์…˜์˜ ๋™์ž‘ ์ˆœ์„œ

  1. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ๋‹ค. (์‚ฌ์šฉ์ž๊ฐ€ ์›น์‚ฌ์ดํŠธ ์ ‘๊ทผ)
  2. ์„œ๋ฒ„๋Š” ์ ‘๊ทผํ•œ ํด๋ผ์ด์–ธํŠธ์˜ Request-Header ํ•„๋“œ์ธ Cookie๋ฅผ ํ™•์ธํ•˜์—ฌ,
    ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด๋‹น session-id๋ฅผ ๋ณด๋ƒˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
  3. session-id๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์„œ๋ฒ„๋Š” session-id๋ฅผ ์ƒ์„ฑํ•ด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋Œ๋ ค์ค€๋‹ค.
  4. ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ๋Œ๋ ค์ค€ session-id๋ฅผ ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด ์„œ๋ฒ„์— ์ €์žฅํ•œ๋‹ค.
  5. ์ฟ ํ‚ค ์ด๋ฆ„ : JSESSIONID
  6. ํด๋ผ์ด์–ธํŠธ๋Š” ์žฌ์ ‘์† ์‹œ, ์ด ์ฟ ํ‚ค(JSESSIONID)๋ฅผ ์ด์šฉํ•˜์—ฌ session-id ๊ฐ’์„ ์„œ๋ฒ„์— ์ „๋‹ฌ.

์ฟ ํ‚ค์™€ ์„ธ์…˜ ์ฐจ์ด (ํ‘œ!)

  • ์“ฐ๋ฉด์„œ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด์ž๋ฉด, ์ฟ ํ‚ค์™€ ์„ธ์…˜์˜ ๊ฐ€์žฅ ํฐ ์ฐจ์ด๋Š” ์ €์žฅ์œ„์น˜๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด๋‹ค. ์ฟ ํ‚ค๋Š” ํด๋ผ์ด์–ธํŠธ ์ชฝ์— ์ €์žฅ์ด ๋˜๋Š” ํ˜•ํƒœ์ด๊ณ , ์„ธ์…˜์€ ์›น์„œ๋ฒ„์— ์ €์žฅํ•ด์„œ ํ™•์ธํ•˜๋Š” ์‹์œผ๋กœ ์ง„ํ–‰์ด ๋œ๋‹ค. ์„œ๋ฒ„์ชฝ์—์„œ session_id๋ฅผ ํ™•์ธํ•˜๊ณ  ์—†์œผ๋ฉด ๋ณด๋‚ด์ฃผ๊ณ  ์žˆ์œผ๋ฉด ํ•ด๋‹น session_id๋ฅผ ์ฐพ์•„์„œ reponse๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

๐Ÿค ์›น ํŽ˜์ด์ง€์—์„œ ํผ์„ ์ „์†ก๋ฐ›์œผ๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์— ์ฟ ํ‚ค๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ์ฝ”๋“œ

# app.py

@app.route('/')
def index():
   return render_template('index.html')
   
@app.route('/setcookie', methods = ['POST', 'GET'])
def setcookie():
   if request.method == 'POST':
     user = request.form['nm']

     resp = make_response("Cookie Setting Complete")
     resp.set_cookie('userID', user)
   
   return resp
   
@app.route('/getcookie')
def getcookie():
    name = request.cookies.get('userID')
    return '<h1>welcome ' +name+ '</h1>'

if __name__ == '__main__':
    app.run(debug = True)

# ํ•ด๋‹น ํผ์€ /setcookie URL๋กœ ์ „์†ก๋˜๋Š”๋ฐ ํผ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ๋ฐ›์„ ๊ฒฝ์šฐ, POST ๋ฉ”์†Œ๋“œ๋กœ /setcookie์— ์˜ค๊ฒŒ ๋จ!
# index.html

<form action = "/setcookie" method = "POST">
         <p><h3>Enter userID</h3></p>
         <p><input type = 'text' name = 'nm'/></p>
         <p><input type = 'submit' value = 'Login'/></p>
      </form>

๐Ÿค ์„ธ์…˜ ์ฝ”๋“œ

์ฟ ํ‚ค์™€ ๋‹ค๋ฅด๊ฒŒ ์„ธ์…˜๊ณผ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋Š” ์„œ๋ฒ„์— ์ €์žฅ๋œ๋‹ค. ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์•ˆ์ „์„ฑ์ด ์ข‹์•„์„œ ๋ณดํ†ต ๋กœ๊ทธ์ธ ๊ด€๋ จ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค. ํ”Œ๋ผ์Šคํฌ์—์„œ ์„ธ์…˜์€ ๋”•์…”๋„ˆ๋ฆฌ์˜ ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜๋ฉฐ ํ‚ค๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์„ธ์…˜์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ด๋‹น ๊ฐ’์„ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ์œ„ํ•œ Key ๊ฐ’์„ ์ฝ”๋“œ์—์„œ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

from flask import Flask, request, session, redirect, url_for
app = Flask(__name__)
app.secret_key = 'get some sleep'

# ์„ธ์…˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•ด๋‹น ๊ฐ’์„ ์•”ํ˜ธํ™”ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด Key๊ฐ’์„ ์ฝ”๋“œ์—์„œ ์ง€์ •ํ•ด์ค˜์•ผํ•จ. 
์•ฝ๊ฐ„ ๋‚˜๋ฅธํ•œ ์˜คํ›„๋‹ˆ๊นŒ get some sleep์œผ๋กœ secret_key๋ฅผ ์ง€์ •ํ•ด์ฃผ๊ธฐ ใ…Žใ…Žใ…Ž

@app.route('/')
def index():
    if 'username' in session:
        username = session['username']
        return 'Logged in as ' + username + '<br>' + \
        "<b><a href = '/logout'>click here to log out </a></b>"

    return "you are not logged in <br><a href = '/loging'></b>" + \
        "click here to log in</b></a>"

# /URL: ์กฐ๊ฑด๋ฌธ if๋ฅผ ์จ์„œ flask ์„ธ์…˜ ์ •๋ณด์•ˆ์— username์ด๋ผ๋Š” ์„ธ์…˜ ์ •๋ณด์˜ ์œ ๋ฌด์— ๋”ฐ๋ผ ๋กœ๊ธด ํ–ˆ๋Š”์ง€ ์•ˆํ–ˆ๋Š”์ง€ ํŒ๋‹จ!
# ๋งจ์ฒ˜์Œ http://127.0.0.1:5000/ ์—ฌ๊ธฐ๋กœ ๋“ค์–ด๊ฐ€๋ฉด else๋กœ ์ฒ˜๋ฆฌ๋ผ์„œ you are not logged in ์ฒ˜๋ฆฌ ๋˜๋Š” ๊ฒƒ.

@app.route('/login', methods = ['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''

    <form action = "" method = "post">
        <p><input type = text name = username></p>
        <p><input type = submit value = Login></p>
    </form>
    '''
# ์‹ค์ œ ๋กœ๊ทธ์ธํ•˜๋Š” form์ด ์žˆ๋Š” /login URL.
# ๋งจ ์ฒจ ์ ‘์†ํ–ˆ์„ ๋•Œ๋Š” GET ๋ฉ”์†Œ๋“œ๋กœ ์š”์ฒญ์ด ์˜ค๋‹ˆ๊นŒ ๋กœ๊ธดํ•˜๊ธฐ ์œ„ํ•œ ํผ ์ „์†ก!
# ํผ์„ ํ†ตํ•ด POST ์š”์ฒญ์ด ์˜ค๋ฉด username์ด๋ผ๋Š” ์„ธ์…˜์„ ์ƒ์„ฑํ•˜์—ฌ ์ž…๋ ฅ๋ฐ›์€ ํผ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์„ธ์…˜ ์ €์žฅํ•˜๊ณ  ๋งจ ์ฒจ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•˜๊ธฐ.

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

# ๋กœ๊ทธ์•„์›ƒ๋„ ํ•ด๋‹น ์„ธ์…˜ ์ •๋ณด๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์—ฐ๊ฒฐ ๋Š๊ธฐ ๊ฐ€๋Šฅ. ์„ธ์…˜ ์ œ๊ฑฐ๋Š” pop ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋จ!!
# ์„œ๋ฒ„์— ์„ธ์…˜ ๊ฐ’์ด ์ €์žฅ๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ €๋ฅผ ๊ป๋‹ค๊ฐ€ ์ผœ๋“ , ์—ฌ๋Ÿฌ๊ฐœ๋ฅผ ์ผœ๋“  ์ด๋ฏธ ๋กœ๊ทธ์ธ์ด ๋œ ์ƒํƒœ๋กœ ํŽ˜์ด์ง€๊ฐ€ ๋ณด์—ฌ์ง.
# ํ•ด๋‹น ์„ธ์…˜ ID ๊ฐ’์€ ํด๋ผ์ด์–ธํŠธ์— ์ฟ ํ‚ค๋กœ ์กด์žฌํ•˜๋ฉฐ, ํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐˆ ๋•Œ๋งˆ๋‹ค ์ธ์ฆ์„ ํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ์ฟ ํ‚ค๋ฅผ ์ง€์›Œ๋ฒ„๋ฆฌ๋ฉด ํด๋ผ์ด์–ธํŠธ ์ธก๋ฉด์—์„œ๋Š” ๋กœ๊ทธ์•„์›ƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Œ.
# ์„œ๋ฒ„ ์ธก์˜ ์„ธ์…˜ ์ •๋ณด๋Š” ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ์‚ฌ๋ผ์ ธ๋ฒ„๋ฆฐ ์„ธ์…˜์„ ๊ณ„์† ์žก๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ํ”Œ๋ผ์Šคํฌ์—์„œ๋„ ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ๊ฐ ์„ธ์…˜์˜ ์œ ํšจ๊ธฐ๊ฐ„์ด ์ •ํ•ด์ ธ ์žˆ์œผ๋ฉฐ ์•„๋ฌด ์„ค์ •๋„ ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ, 31์ผ๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

if __name__ == '__main__':
    app.run(debug = True)
# ๋งŒ์•ฝ ์ง์ ‘ ์„ธ์…˜์˜ ์œ ํšจ๊ธฐ๊ฐ„์„ ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„๋ž˜์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
from datetime import timedelta
from flask import session, app

@app.before_request
def make_session_permanent():
	session.permanent = True
    app.permanent_session_lifetime = timedelta(minutes=5)
  • ์„ธ์…˜์„ print ํ•ด๋ณด์•˜์„ ๋•Œ ๋‚˜์˜ค๋Š” ํ™”๋ฉด์ด๋‹ค. ์„ธ์…˜์•ˆ์— ์žˆ๋Š” username์˜ ํ˜•ํƒœ๊ฐ€ ์ €๋ ‡๊ฒŒ ์ฐํžŒ๋‹ค. ์›น์„œ๋ฒ„์— ์ €์žฅ๋œ username์ด ์Šคํ…”๋ผ์ด๋‹ˆ๊นŒ if ์ ˆ์—์„œ ok, ์„ธ์…˜์— username์„ username์— ๋‹ด๊ณ  ๋กœ๊ทธ์ธ์ด ๋˜์—ˆ๋‹ค๊ณ  ํ•ด์ฃผ๋Š” ๊ฒƒ...!

  • /login์„ ํ•ด์„œ ์•„์ด๋”” ์ž…๋ ฅ ํ›„์— index๋กœ redirect ๋˜๊ณ  ๊ฑฐ๊ธฐ์„œ ์„ธ์…˜์— ์žˆ๋Š” username์ด๋ž‘ ํ™•์ธํ•ด๋ณด๊ณ  ๋กœ๊ทธ์ธ์ด ๋œ๋‹ค. ์•„ ์ˆœ์„œ ํ—ท๊ฐˆ๋ ค... ์ฟ ํ‚ค์™€ ์„ธ์…˜์— ๋Œ€ํ•ด ๊ณต๋ถ€๋ฅผ ํ•˜๋Š”๋ฐ ์ข€ ๋” ์นœ์ˆ™ํ•ด์งˆ ํ•„์š”๊ฐ€ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋ž˜์•ผ ๋‚ด๊ฐ€ flask ๋กœ์ง ์งค ๋•Œ๋„ ์ข€ ๋” ์ˆ˜์›”ํ•  ๋“ฏ...! ๋ณต์Šตํ•˜๊ธฐ ๐Ÿ’ช

์ถœ์ฒ˜1: https://hahahoho5915.tistory.com/32
์ถœ์ฒ˜2: https://blog.naver.com/shino1025/221355012951

profile
๊ฐœ๋ฐœ ๊ธฐ๋ก

0๊ฐœ์˜ ๋Œ“๊ธ€