python/웹

[파이썬 서버] 간단하게 파이썬 웹페이지 만들기 ( Flask ) [2]

끼발자 2021. 8. 17. 17:13
반응형

서버를 만들었으면 다음은?

데이터를 뿌린다 ( O )

 

SQLAlchemy 를 이용해서 db를 구성하자.

flask는 db기능을 포함하지 않으므로, 

flask_sqlalchemy를 이용해서 db를 구성해야한다.

우선, 패키지를 다운로드하자.

 

pip install flask_sqlalchemy

 

이전 포스트에서는 단순히 url을 통해서 텍스트를 화면에 출력했다.

하지만 db를 설계하고 url을 통해서 db를 직접 수정하기 위해서 좀 더 복잡한 코드가 불가피하게 사용된다.

최대한 자세하게 설명해보겠지만, 그래도 어려우면 댓글을 통해 소통해보자.

 

우선, 이전에 사용된 코드를 보자.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def main():
    return 'Hi'

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

 

html관련 웹 강의를 수강하면 로그인 페이지를 만드는 예제가 많다.

이번 포스트도 지겹겠지만 user_name과 password를 입력받는 구조를 짜보자.

main.py 맨 위에 다음과 같은 클래스를 구성한다.

from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash,check_password_hash
db = SQLAlchemy()
class User(db.Model):
    __table_name__ = 'user'
    id = db.Column(db.Integer,primary_key=True)
    user_name = db.Column(db.String(100),unique=True,nullable=False)
    password = db.Column(db.String(120),nullable=False)

    def set_password(self,password):
        self.password = generate_password_hash(password)

    def check_password(self,password):
        return check_password_hash(self.password,password)

    def __init__(self,user_name,password,**kwargs):
        self.user_name = user_name
        self.set_password(password)

    def __repr__(self):
        return f"<User('{self.id}','{self.user_name}')>"

 

table_name을 user로 만들어주고, id, user_name,password를 컬럼으로 갖는 db구조를 설계한다.

id : 기본키, integer

user_name : String, unique, not null

password : String, not null

set_password / check_password 는 입력 받은 password를 hash형태로 변환시켜 암호화하는 방식이다.

예시를 들어보면,

password를 generate_password_hash를 통해 다른 값으로 변환시키고, check_password_hash를 통해 확인하는 모습이다.

 

User 클래스를 통해 객체를 생성할 때, user_name과 password를 입력한다.

 

 

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' #db path
app.config['SECRET_KEY'] = 'user secret key' 
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

위와 같이 추가해주자.

 

다음으로 url을 통해서 db에 데이터를 넣어보자.

웹 통신 방식에는 get/post/option 등등 많지만,

html을 최대한 빼서 진행하려고 하니 get방식으로 진행하자.

get 방식이란?

url 자체에 데이터를 넣어서 전송하는 방식.

 

그럼 db에 접근할 새로운 url을 만들어보자.

from flask import request #request : get방식으로 담아온 parameter를 읽어와라
@app.route('/register',methods='GET') # 이 url은 get 방식이다.
def register():    
    user_name = request.args.get('user_name') # url에 user_name으로 받아온 데이터를 user_name에 담겠다.
    password = request.args.get('password') # 상동
    user = User(user_name,password) # model.py 에서 작성한 db구조에 맞게 name,password를 넣어 객체를 생성
    try:
    	db.session.add(user) # db에 객체를 추가
    	db.session.commit()  # 전송
    	return f'Success commit NAME : {user_name}, PASSWORD : {bool(password)}'
    except Exception as e:
    	return f'Error is {e}'

올바르게 전송했다면, 성공 커밋과 함께 이름과 암호가 출력된다. 물론 암호는 bool로 True만 리턴된다.

try~except를 통해, 실패시에 에러메세지를 리턴한다.

 

코드로는 구현했으니, 이제 작동되는지 확인해야한다.

우리는 url메소드를 get 으로 정했으니, 다음과 같은 url을 통해서 명령을 내려준다.

your_flask_url/register?user_name=user&password=password

참 쉽다. 직관적이다.

?뒤의 값들이 전부 parameter로 전달되는 값이다. url을 구성할 때, user_name과 password를 인자로 받기로 했으니

원하는 값들을 &로 묶어서 전달해준다.

 

지금까지의 코드.

from flask import Flask,request,flash,render_template
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash,check_password_hash
app = Flask(__name__)
DB_PATH = 'sqlite:///site.db'
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = DB_PATH
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SECRET_KEY'] = 'kiholee'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class User(db.Model):
    __table_name__ = 'user'
    id = db.Column(db.Integer,primary_key=True)
    user_name = db.Column(db.String(100),unique=True,nullable=False)
    password = db.Column(db.String(120),nullable=False)

    def set_password(self,password):
        self.password = generate_password_hash(password)

    def check_password(self,password):
        return check_password_hash(self.password,password)

    def __init__(self,user_name,password,**kwargs):
        self.user_name = user_name
        self.set_password(password)

    def __repr__(self):
        return f"<User('{self.id}','{self.user_name}')>"



@app.route('/')
def main():
    flash('TEST')
    return 'Hi'

@app.route('/register',methods=['GET'])
def register():
    user_name = request.args.get('user_name')
    password = request.args.get('password')

    user = User(user_name,password)
    try:
        db.session.add(user)
        db.session.commit()
        return f'Success commit \nNAME : {user_name}, PASSWORD : {bool(password)}'
    except Exception as e:
        return f'Some Error Occured\n{e}'


if __name__ == '__main__':
    db.create_all()
    app.run()

이제 만들어진 db를 조회하는 기능을 만들어보자.

 

우선, html을 이용해 화면을 구성해보자.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Falsk APP</title>
</head>
<body>
<table>
    {% for i in user %}
    <tr>
        <td>{{ i.id }}</td>
        <td>{{ i.user_name }}</td>
        <td>{{ i.password }}</td>
    </tr>
    {% endfor %}
</table>
</body>
</html>

 

flask에서 화면 렌더링하는 html파일은 모두 동일한 디렉터리 내에 templates라는 폴더 아래에 위치해야한다.

이전 포스트에서는 프로젝트 구조가

 

project

ㄴmain.py

 

였다면, 화면에 출력되는 html파일들을 담을 디렉터리가 추가적으로 필요하다.

 

project

ㄴtemplates

    ㄴdb.html

ㄴmain.py

 

프로젝트를 위처럼 만들었다면 이제 끝이 보인다.

 

@app.route('/db')
def db_check():
    user = User.query.all()
    return render_template('db.html',user = user)

db라는 url을 만들고, 위와같이 구성한다.

html 안에 {% for i in user %} 라는 구문이 있다.

user라는 변수를 넘겨줘야 하는데, render_template을 통해 db.html에 (왼쪽)user 라는 이름에 (오른쪽) user를 할당한다는 뜻이다.

user객체는 id, user_name, password를 가지고있다. __repr__ 함수로 return되는 값만 볼 수 있지만, 객체를 전달하므로 

id, user_name, password 모두 넘겨주게된다.

db.html을 보면, user에 담겨있는 정보들을 반복문을 통해 테이블형태 ( tr / td )로 출력해준다.

 

순서대로 id, user_name, password 가 출력되는 것을 볼 수 있다.

password는 generate_password_hash로 변환된 암호를 출력한다.

 

 

반응형