[TIL]21.07.27 flask 기초

Seung Joo·2021년 7월 27일
0

TIL

목록 보기
28/31
post-thumbnail

Python Flask 기본

  1. pip install flask
  2. flask_app 폴더 생성
  3. flask_app 폴더 안에 __init__.py 생성

1. 기본 앱 만들기

🔗flask_app/__init__.py

from flask import Flask

# 앱 생성
app = Flask(__name__)

# 기본 라우트 생성
@app.route('/')
'''
기본 접속 페이지의 라우터 `127.0.0.1:5000` or localhost:5000으로 접속
'''
# 기본 페이지 성생
def index():
	return "Hello World!"

기본적인 구조이지만 복잡해지게 되면 Circular Import Error를 주의해야하고, Flask는 장점인 유연성이 코드의 작성 방향에 혼란을 줄 수 있기 때문에 application factory pattern을 확인하고 따르도록 해야한다.
Flask application factory pattern

Create_app

from flask import Flask


db = SQLAlchemy()

def create_app():
    app = Flask(__name__)


    # 기본 라우트 생성
    @app.route('/')
    '''
    기본 접속 페이지의 라우터 `127.0.0.1:5000` or localhost:5000으로 접속
    '''
    # 기본 페이지 성생
    def index():
    	return "Hello World!"

    return app
if __name__ == '__main__':
    app=create_app()
    app.run(debug=True) # 디버그 모드 실행

실행

방법 1

  • 터미널에서 FLASK_APP=flask_app flask run을 통해 실행

방법 2

  1. 터미널에서 export FLASK_APP=flask_app
  2. flask run을 통해 실행

export FLASK_DEBUG=1 로 환경변수 추가해주면 디버그 모드로 실행가능
❗❗주의할점

  • 터미널의 현재 위치는 flask_app 외부에 있어야 한다.
  • ls or dir 시 flask_app이 보여야함.

2. flask Blue print

Flask는 블루프린트라는 기능을 사용하여 라우트를 나눠서 관리할 수 있음

  1. Flask_app 폴더 안에 routes 폴더 생성
  2. main_route.py 생성

🔗flask_app/routes/main_route.py

from flask import Blueprint, render_template



bp = Blueprint('main', __name__)

@bp.route('/')
def index():
    return "<h1>Home Page</h1>"

@bp.route('/about')
def about():
    return "<h1>About Page</h1>"

@bp.route('/user')
def user():
    return "<h1>User Page</h1>"

다음과 같이 블루프린트를 통해서 관리 가능
라우터의 경우 엔드포인트를 지정하여 따로 페이지를 관리하고 페이지 내의 동작 내용을 설정함

\__init__.pycreate_app 함수에
from flask_app.routes.main_route import bp as main_bp
와 같은 형태로 import 해주고
app.register_blueprint(main_bp)
를 통해 앱에 추가해준다.

3. flask templates

flask는 templates 폴더를 통해서 html을 관리한다.
jinja를 통해 python 언어를 사용하여 html을 작성할 수 있다.

  1. flask_app 폴더 안에 templates 폴더 생성
  2. index.html 생성

🔗flask_app/templates/index.html

<!DOCTYPE html>
<html>
    <head>
        <title>
            Test Page
        </title>
        <h1>Test Page</h1>
    </head>
    <body>
        {% if texts %}
            {% for text in texts %}
            <div> {{text}} </div>
            {% endfor %}
        {% endif %}
    </body>
</html>

다음과 같이 jinja 표현식과 함께 사용한다.

  • 변수선언 : {{ variable }}
  • 표현식 : {% for %} {% endfor %} 또는 {% if 표현식 %} {% endif %}
    과 같이 사용할 수 있다.

main_routerender_template 함수를 활용하여 페이지 및 변수 할당

🔗flask_app/routes/main_route.py

from flask import Blueprint, render_template

bp = Blueprint('main', __name__)

@bp.route('/')
def index():
    texts = ['first', 'second', 'third']
    return render_template('index.html', texts=texts)

@bp.route('/about')
def about():
    return "<h1>About Page</h1>"

@bp.route('/user')
def user():
    return "<h1>User Page</h1>"

init.py 에서 앱에 블루프린트 등록하기

🔗flask_app/init.py

from flask import Flask


def create_app():
    app = Flask(__name__)

    # 블루프린트 등록
    from flask_app.routes.main_route import bp as main_bp
    app.register_blueprint(main_bp)

    return app


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

📄결과 페이지

if문과 for문 안에 있는 내용이 잘 출력된 것을 볼 수 있다.

4. flask sqlalchemy

  1. pip install flask sql-alchemy 를 통해 설치
  2. flask_app 에 models 폴더 생성
  3. user_model.py, post_model.py 생성
  4. __init__.py 에 데이터 베이스 객체 생성

🔗flask_app/init.py


from flask import Flask
# SQLalchemy import 해주기
from flask-sqlalchemy import SQLalchemy

데이터 베이스 객체 생성
db = SQLAlchemy()
# CLI 테스트시 create_app 주석처리 후
# 아래의 코드를 실행
# app = Flask(__name__)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
# db = SQLAlchemy(app)


def create_app():
    app = Flask(__name__)
    # 데이터베이스 URI 설정
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
    
    # 데이터베이스에 앱 할당
    db.init_app(app)
    
    # 블루프린트 등록
    from flask_app.routes.main_route import bp as main_bp
    app.register_blueprint(main_bp)

    return app


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

🔗flask_app/models/user_model.py


from flask_app import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    posts = db.relationship('Post', backref='author')

    def __repr__(self):
        return f"User ('{self.id}', '{self.username}', '{self.email}')"

🔗 flask_app/models/post_model.py


from flask_app import db

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post ('{self.id}', '{self.title}')"

패키지가 설치된 가상환경 위에서 CLI를 통해 확인한다.

CLI를 통해 데이터 베이스 확인

User table 확인

$ python
>>> from flask_app import db
>>> from flask_app.models.user_model import User
>>> from flask_app.models.post_model import Post
>>> db.create_all() # 처음 데이터베이스 테이블을 생성해준다.
>>> # db.drop_all() 함수를 사용하면 데이터 베이스 테이블을 초기화해준다.
>>> user_1 = User(username='tobenac', email='rsj9987@velog.io', password='password')
>>> user_2 = User(username='Malpoi', email='Malpoi@demo.com', password='password2')
>>> db.session.add(user_1)
>>> db.session.add(user_2)
>>> db.session.commit()
>>> # User Database Query
>>> User.query.all()
[User ('1', 'tobenac', 'rsj9987@velog.io'), User ('2', 'Malpoi', 'Malpoi@demo.com')]
>>> # filter_by 사용예시
>>> User.query.filter_by(username='tobenac').first()
User ('1', 'tobenac', 'rsj9987@velog.io')
>>> user = User.query.filter_by(username='tobenac').first()
>>> # user.변수이름 을 통해서 접근할 수 있다.
>>> user.id
1
>>> user.username
'tobenac'

리스트의 경우에는 for loop를 통해서 각각의 원하는 값을 가져올 수 있다.

for user in users:
    print(user.id)
    print(user.username)

Post table 확인

>>> post_1 = Post(title='blog 1', content='first content!', user_id=user.id)
>>> post_2 = Post(title='blog 2', content='second content!', user_id=user.id)
>>> db.session.add(post_1)
>>> db.session.add(post_2)
>>> db.session.commit()
>>> Post.query.all()
[Post ('1', 'blog 1'), Post('2', 'blog 2')]
>>> # relationship 접근
>>> user.username
'tobenac'
>>> user.posts
[Post ('1', 'blog 1'), Post('2', 'blog 2')]
>>> for post in user.posts:
...    print(post.title)
...
Blog 1
Blog 2

🐘postgreSQL database 사용시

🔗flask_app/init.py


from flask import Flask
# SQLalchemy import 해주기
from flask-sqlalchemy import SQLalchemy

데이터 베이스 객체 생성
db = SQLAlchemy()


def create_app():
    app = Flask(__name__)
    # 데이터베이스 URI 설정
    app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@host_server:5432/databasename'
    
    # 데이터베이스에 앱 할당
    db.init_app(app)
    
    # 블루프린트 등록
    from flask_app.routes.main_route import bp as main_bp
    app.register_blueprint(main_bp)

    return app


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

init은 위와같이 변경해주고 user_model, post_model은 그대로 사용합니다.

# 먼저 필요한 app 생성함수와 db, 테이블을 불러옵니다.
>>> from flask_app import create_app
>>> from flask_app import db
>>> from flask_app.models.user_model import User
>>> from flask_app.models.post_model import Post
>>> # app 객체 생성
>>> app = create_app()
>>> # app에 접속하여 db에 접근할 수 있습니다.
>>> with app.app_context():
>>> ...    db.create_all() # tap을 사용하여 공백을 만들어줘야합니다.

다음과 같이 실행한 후에 database gui 툴을 이용하여 확인하거나 ElephantSQL에서 테이블이 생성되었는지 확인합니다.

📌cli에서 확인할 경우

>>> with app.app_context():
>>>...    db.metadata.tables.keys()
>>> # 위의 코드로 테이블 명을 확인하고
>>>...    db.metadata.tables.value()
# 다음의 코드로 내가 만든 테이블의 스키마를 확인합니다.

를 통해서 테이블을 확인합니다.
with app.app_context()를 통해서 접근하여 sqlalchemy문법을 그대로 사용할 수 있으니 Documentation이나 위의 코드들을 참고하여 사용해보면서 확인해보면 됩니다.

참조

Flask Documentation
Flask SQLAlchemy Documentation
Flask Tutorial youtube - Corey Schafer

profile
조금씩 천천히

0개의 댓글