[Flask] 파이보 - 프로젝트 구조, 애플리케이션 팩토리, 블루프린트로 라우팅 함수 관리

파이보 프로젝트 구조


├── pybo/
│      ├─ __init__.py
│      ├─ models.py
│      ├─ forms.py
│      ├─ views/
│      │   └─ main_views.py
│      ├─ static/
│      │   └─ style.css
│      └─ templates/
│            └─ index.html
└── config.py

 

  • models.py : 데이터베이스 처리
  • forms.py : 서버로 전송된 폼 처리
  • views 디렉터리 : 화면 구성
  • static 디렉터리 : css, javascript, images 파일 저장
  • templates 디렉터리 : html 파일 저장
  • config.py : 프로젝트 환경 설정

 

 

 

플라스크 애플리케이션 팩토리


app = Flask(__name__)

: app 객체를 전역으로 사용하면 순환 참조와 같은 오류 발생 확률이 증가

: 이를 해결하기 위해 애플리케이션 팩토리(application factory) 사용

 

 

from flask import Flask

def create_app(): # 애플리케이션 팩토리
	app = Flask(__name__)
    
    @app.route('/')
    def hello_pybo():
    	return 'Hello, pybo!'
    
    return app

[파일명: myproject\pybo\__init__.py]

 

 

: create_app 함수가 app 객체를 생성해 반환

: 여기서 사용된 create_app 함수가 바로 애플리케이션 팩토리

: create_app은 플라스크 내부에서 정의된 함수이므로 이름 변경 불가

 

 

 

블루프린트로 라우팅 함수 관리


문제 : 새로운 URL 매핑이 필요할 때마다 라우팅 함수가 추가되어 create_app 함수가 복잡해짐

 

 

-> 해결법

  • 블루프린트(Blueprint) : URL과 함수의 매핑을 체계적으로 관리하기 위해 사용하는 도구
  • 라우팅 함수 : 웹사이트에서 어떤 주소(URL)를 입력했을 때, 그 주소에 맞는 페이지나 정보를 보여주는 방법을 정하는 함수

 

 

블루프린트 생성


bp = Blueprint('main', __name__, url_prefix='/')
  • 'main' : 블루프린트의 별칭. url_for 함수에서 사용됨
  • __name__ : 모듈명이 인수로 전달됨
  • url_prefix : 라우팅 함수의 애너테이션 URL 앞에 기본으로 붙일 접두어 URL

 

 

(ex. if url_prefix='/', hello_pybo 함수를 호출하는 URL은 localhost:5000/

       else if url_prefix='/main', hello_pybo 함수를 호출하는 URL은 localhost:5000/main/)

from flask import Blueprint

bp = Blueprint('main', __name__, url_prefix='/')

@bp.route('/')
def hello_pybo():
	return 'Hello, Pybo!'

[파일명: myproject\pybo\views\main_views.py]

 

 

블루프린트 등록


from flask import Flask

def create_app():
	app = Flask(__name__)
    
    from .views import main_views
    app.register_blueprint(main_views.bp)
    
    return app

[파일명: myproject\pybo\__init__.py]

 

 

 

블루프린트에 라우팅 함수 추가


from flask import Blueprint

bp = Blueprint('main', __name__, url_prefix='/')

@bp.route('/hello')
def hello_pybo():
	return 'Hello, Pybo!'
    
@bp.route('/')
def index():
	return 'Pybo index'

[파일명: myproject\pybo\views\main_views.py]

 

http://localhost:5000

 

http://localhost:5000/hello