본문 바로가기

내일배움캠프

웹개발 복습

오늘은 웹개발의 백엔드 부분을 복습하기로 했다. Flask를 중심으로 이해한 내용을 적어주자.

 

Flask를 사용하려면 기본적으로 서버의 구조가 맞아야한다.

venv폴더(가상환경 폴더)
templates폴더(html 폴더)
app.py 파일(백엔드 코드)

 

가상환경을 구축하고 templates폴더와 app.py 파일을 만드는 것이 가장 기본이다.

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/mypage')
def mypage():
    return render_template('mypage.html')

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

app.py

<!DOCTYPE html>
<html>
<head>
    <title>Home Page</title>
</head>
<body>
    <h1>Welcome to the Home Page!</h1>
    <p>Click <a href="/mypage">here</a> to visit mypage.</p>
</body>
</html>

index.html

<!DOCTYPE html>
<html>
<head>
    <title>My Page</title>
</head>
<body>
    <h1>Welcome to My Page!</h1>
    <p>Click <a href="/">here</a> to go back to the Home Page.</p>
</body>
</html>

mypage.html

 

 

나는 연습삼아서 메인페이지 역할을 할 index.html과 다른 페이지 역할을 해줄 mypage.html을 생성해서 서로를 하이퍼링크로 연결했다.

즉, app.py의 각 부분이 html파일과 연결되어 url주소를 가지는 것이다.

 

app.py에 변수를 선언해서 해당 변수를 html에서 사용해보자.

@app.route('/prac')
def prac():
    name = '이름'
    lotto = [16, 18, 22, 43, 32, 11]
    
    context = {
        'name': name,
        'lotto': lotto
    }
    
    return render_template('prac.html', data = context)

name 변수안에 '이름'을 저장하고 lotto변수 안에 리스트를 저장하자.

context 딕셔너리에 두 변수를 넣어주고 data = context를 통해서 prac.html로 넘겨준다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>안녕, {{ data.name }}야</h1>
    <h1>로또번호: {{ data.lotto }}</h1>
</body>
</html>

data.변수명으로 해당 변수를 html로 불러올 수 있다.

출력예시

 

@app.route('/lotto')
def lotto():
    name = '이름'
    lotto = [16, 18, 22, 43, 32, 11]
    
    def generate_lotto_numbers():
        numbers = list(range(1, 46))
        lotto_numbers = random.sample(numbers, 6)
        lotto_numbers.sort()
        return lotto_numbers

    random_lotto = generate_lotto_numbers()
    
    def count_common_numbers(list1, list2):
        set1 = set(list1)
        set2 = set(list2)
    
        common_numbers = set1 & set2
        return len(common_numbers)
    
    prize = count_common_numbers(lotto, random_lotto)

    context = {
        'name': name,
        'lotto': lotto,
        'random_lotto': random_lotto,
        'prize': prize
    }

    return render_template('lotto.html', data=context)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>lotto</title>
</head>
<body>
    <h1>안녕, {{ data.name }}야</h1>
    <h1>로또번호: {{ data.lotto }}</h1>
    <h1>로또번호: {{ data.random_lotto }}</h1>
    <h1>당첨 개수: {{ data.prize }}</h1>
    
</body>
</html>

 

app.py의 해당 html 부분을 이용해서 백엔드를 구성할 수 있다. 위의 예시는 name에는 이름을, lotto에는 지정된 번호를, random_lotto에는 랜덤 번호를, prize에는 lotto와 random_lotto에서 일치하는 숫자의 갯수를 각각 저장해서 lotto.html로 넘겨준 후 출력하는 과정이다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>movie</title>
</head>
<body>
    <h1>영화 검색 사이트</h1>
    <form action="movie">
        <input type="text"  name = 'query'>
        <button type="submit">검색</button>
    </form>
    
</body>
</html>

위의 응용으로 새롭게 작성될 movie.html이다. action에는 데이터를 보낼 곳을 지정하고 name은 데이터의 이름을 지정한 것이다. text를 입력받으며 버튼을 누르면 제출이 된다.

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>movie</title>
</head>
<body>
    <h1>영화 검색 사이트</h1>
    <form action="{{ url_for('movie')}}">
        <input type="text"  name = 'query'>
        <button type="submit">검색</button>
    </form>
    
</body>
</html>
@app.route('/movie')
def movie():
    print(request.args.get('query'))
    return render_template('movie.html')

 

데이터를 보낼 url주소를 movie로 설정하고 데이터의 이름은 query라고 지었다. 그리고 app.py로 돌아와서 movie에 request.args.get('query')를 통해서 query의 데이터를 받아온다.

즉, movie.html의 인풋창에 텍스트를 입력하면 app.py에서 출력된다는 것이다.

'데이터 입력예시'라고 입력

 

데이터 출력

원래는 여기서 실습까지 진행할 예정이었으나 예시로 주어진 영화진흥위원회의 api값이 만료되어서 더 진행하지는 못했다...(홈페이지를 통해서 접근해도 마찬가지였다.) 다행히 실습은 지난번에 해보았고 이번에는 복습을 하는 것이니 다시 한번 집중해서 강의를 보면서 마무리를 할 예정이다.

 

마지막으로 html에서 받은 데이터를 다시 html로 출력해보았다.

<!DOCTYPE html>
<html>
<head>
    <title>Home Page</title>
</head>
<body>
    <h1>Welcome to the Home Page!</h1>
    <p> <a href="/mypage">이곳</a>을 클릭하면 mypage로 이동합니다.</p>
    <p> <a href="/lotto">이곳</a>을 클릭하면 lotto로 이동합니다.</p>
    <p> <a href="/movie">이곳</a>을 클릭하면 movie로 이동합니다.</p>

    <form action="{{ url_for('index')}}">
        <input type="text"  name = 'mytext'>
        <button type="submit">입력</button>
    </form>

    <h1>안녕, {{ data.my_data }}야</h1>
</body>
</html>
@app.route('/')
def index():
    myinput = request.args.get('mytext')
    
    context = {
        'my_data': myinput
    }
    return render_template('index.html', data = context)

 

작동순서대로 정리해보자.

 

<form action="{{ url_for('index')}}">
        <input type="text"  name = 'mytext'>
        <button type="submit">입력</button>
    </form>

텍스트타입의 데이터를 입력받고 mytext라고 명명한다.

'입력'버튼을 누르면 app.py의 index로 전달된다.

@app.route('/')
def index():
    myinput = request.args.get('mytext')
    
    context = {
        'my_data': myinput
    }
    return render_template('index.html', data = context)

전달받은 mytext는 app.py에서 myinput 변수에 저장한다. 그리고 그것을 context 딕셔너리에 담고 my_data라는 키값을 붙인다.

context 딕셔너리를 data라는 이름으로 index.html로 전달한다.

<h1>안녕, {{ data.my_data }}야</h1>

다시 index.html로 돌아와서 받은 데이터를 출력해준다.

 

이렇게 입력하면

 

이렇게 출력된다.

 

복습중이라서 정확하지 않은 내용을 적었을지도 모른다. 내가 이렇게 이해했다 정도로 기억하고 넘어갈 생각이다. 강의를 보면서 이해했다고 생각하더라도 적어두지 않으면 금방 잊어버리는 경우가 많으니...