[Flask] Blueprint로 웹 애플리케이션 구조화

2025. 1. 14. 02:31Calender Website

기존 폴더 구조는 다음과 같다.

calendar_app/              # 프로젝트 루트 디렉토리
├── app/                      # 애플리케이션 패키지
│   ├── __init__.py          # 앱 초기화 (Flask 앱 생성, 설정 로드, DB 초기화)
│   ├── models/              # 데이터베이스 모델 폴더
│   │   └── __init__.py      # 모델 패키지 초기화
│   ├── routes/              # URL 라우트 처리 폴더
│   │   └── main.py.
│   ├── static/              # 정적 파일 폴더
│   │   ├── css/            # CSS 파일들 (스타일링)
│   │   ├── js/             # JavaScript 파일들 (클라이언트 측 로직)
│   │   └── images/         # 이미지 파일들
│   └── templates/           # HTML 템플릿 폴더 (Jinja2 템플릿)
├── config.py                # 설정 파일 (DB URL, 시크릿 키 등)
├── requirements.txt         # 프로젝트 의존성 목록
└── run.py                   # 애플리케이션 실행 스크립트

 

routes/main.py 에 모든 라우터들을 넣어 사용했는데, 개발을 하다보니 페이지를 랜더링하는 라우터들 따로, 데이터베이스를 조작하는 라우터들 따로 관리하고 싶어졌다.


1. routes 폴더에 views.py, api.py 파일 생성 후 내용 변경

기존 main.py에 있던 라우터들 중 , 페이지를 랜더링하는 라우터들은 views.py로 넣고 데이터베이스를 조작하는 라우터들은 api.py에 넣어준다. Blueprint도 views로 이름을 변경해주면 라우터들을 기능별로 분류하고 관리하기 편리하다.

 <views.py>

from flask import Blueprint, render_template

views = Blueprint('views', __name__)

@views.route('/')
def welcome():
    return render_template('welcome.html')

@views.route('/sign_up')
def sign_up():
    return render_template('sign_up.html')

@views.route('/sign_in')
def sign_in():
    return render_template('sign_in.html')

 

<api.py>

import os
from flask import Blueprint, jsonify, render_template, request
from app.models.model import User
from app import db
from werkzeug.utils import secure_filename

api = Blueprint('api', __name__)

@api.route('/confirm_email', methods=['POST'])
def confirm_email():
    data = request.json
    user_email = data.get('userEmail')

    user = User.query.filter_by(email=user_email).first()
    if user:
        return jsonify({
            'available' : False
        })
    else:
        return jsonify({
            'available' : True
        })

 

<새로운 폴더 구조>

calendar_app/              # 프로젝트 루트 디렉토리
├── app/                      # 애플리케이션 패키지
│   ├── __init__.py          # 앱 초기화 (Flask 앱 생성, 설정 로드, DB 초기화)
│   ├── models/              # 데이터베이스 모델 폴더
│   │   └── __init__.py      # 모델 패키지 초기화
│   ├── routes/              # URL 라우트 처리 폴더
│   │   ├── views.py         # 페이지 랜더링 라우터 관리
│   │   └── api.py           # 데이터 베이스 라우터 관리
│   ├── static/              # 정적 파일 폴더
│   │   ├── css/            # CSS 파일들 (스타일링)
│   │   ├── js/             # JavaScript 파일들 (클라이언트 측 로직)
│   │   └── images/         # 이미지 파일들
│   └── templates/           # HTML 템플릿 폴더 (Jinja2 템플릿)
├── config.py                # 설정 파일 (DB URL, 시크릿 키 등)
├── requirements.txt         # 프로젝트 의존성 목록
└── run.py                   # 애플리케이션 실행 스크립트

2. app\__init__.py 파일 변경

기존에는 main 블루프린트를 등록해서 사용했으므로 이제 새로 만든 view, api 블루프린트를 등록하여 초기화해준다.

<app/__init__.py>

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import Config

db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)
    
    db.init_app(app)

    from app.routes.views import views
    from app.routes.api import api

    app.register_blueprint(views)
    app.register_blueprint(api)
    
    return app

3. 기존 사용하던 라우터 변경

HTML에서 a href로 url를 달때 main 블루프린트로 사용했는데 이를 적절하게 변경한다.

    <div id = "sign-up" class="select-sign"><a href="{{ url_for('views.sign_up') }}">Sign up</a></div>