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
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) # 디버그 모드 실행
FLASK_APP=flask_app flask run
을 통해 실행export FLASK_APP=flask_app
flask run
을 통해 실행❗ export FLASK_DEBUG=1
로 환경변수 추가해주면 디버그 모드로 실행가능
❗❗주의할점
flask_app 외부
에 있어야 한다.Flask는 블루프린트라는 기능을 사용하여 라우트를 나눠서 관리할 수 있음
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__.py
의 create_app
함수에
from flask_app.routes.main_route import bp as main_bp
와 같은 형태로 import 해주고
app.register_blueprint(main_bp)
를 통해 앱에 추가해준다.
flask는 templates 폴더를 통해서 html을 관리한다.
jinja
를 통해 python 언어를 사용하여 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_route
에 render_template
함수를 활용하여 페이지 및 변수 할당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>"
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문 안에 있는 내용이 잘 출력된 것을 볼 수 있다.
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)
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}')"
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를 통해 확인한다.
$ 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_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
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에서 테이블이 생성되었는지 확인합니다.
>>> 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