이번 글은 추가적인 구현에 대한 얘기는 하지 않고
프로젝트 전체의 흐름과 데이터의 전달에 대해 설명할 예정이다.
이전 글들과 설명이 중복 되는 내용도 있겠지만 자료형까지 조금 더 원리를 자세히 설명할 예정이다.
0. flask 앱
flask는 기본적으로 create_app()을 통해 application 객체를 만드는 것에서 시작한다.
이 프로젝트의 경우 __init__.py 파일에서 create_app()을 정의했다.
1. DB처리
'메인홈페이지의 새 책 데이터를 가져오기'를 예시로 설명한다.
1-1. .env 파일
먼저 .env 파일에
DB_USER=root
DB_PASSWORD=
DB_HOST=localhost
DB_NAME=library_db
SECRET_KEY=
이런 식으로 SQL 서버에 들어가기 위해 필요한 값들을 저장해 놓는다.
1-2. __init__.py 파일
이 값들은 __init__.py에서 아래와 같은 코드를 사용해 app.config라는 dictionary에 저장된다.
# .env 파일에서 환경 변수 불러오기
app.config['DB_USER'] = os.environ.get('DB_USER')
app.config['DB_PASSWORD'] = os.environ.get('DB_PASSWORD')
app.config['DB_HOST'] = os.environ.get('DB_HOST')
app.config['DB_NAME'] = os.environ.get('DB_NAME')
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
# db.py에서 사용할 DB 설정 저장
app.config['DB_CONFIG'] = {
'user': app.config['DB_USER'],
'password': app.config['DB_PASSWORD'],
'host': app.config['DB_HOST'],
'database': app.config['DB_NAME']
}
이 값들을 DB_CONFIG라는 새 dictionary에 한번에 저장해 sql 서버 연결이 용이해지게 한다.
1-3. db.py
이 파일의 get_db_connection()을 통해 sql 서버에 접근하고 이 연결 정보를 변수로 담아놓는다.
def get_db_connection():
conn = mysql.connector.connect(**current_app.config['DB_CONFIG'])
return conn
각 쿼리를 저장하는 함수들이 있고 이 함수들은 execute_query()를 통해 쿼리를 실행한다.
execute_query()는 서버와 연결 후 쿼리를 실행하고 연결을 종료하는 함수이다.
여기서 conn.cursor(dictionary=True)의
옵션이 없다면 (1, 'pw1', 1)과 같은 tuple로 값이 반환된다.
이 옵션이 있다면 [{'id': 1, 'pw': 'pw1', 'role': 1}]와 같이 가공이 더 쉬운 dictionary로 리턴된다.
만약 쿼리 실행 결과가 여러개라면 이 dictionary들의 list로 값이 반환된다.
def execute_query(query, params=None, fetch=None):
conn = get_db_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute(query, params or ())
if fetch == 'all':
result = cursor.fetchall()
elif fetch == 'one':
result = cursor.fetchone()
else:
conn.commit()
result = None
cursor.close()
conn.close()
return result
def get_newbooks():
query = '''
SELECT * FROM book_data
ORDER BY book_code DESC
LIMIT 6;
'''
return execute_query(query, fetch='all')
1-4. routes.py
위의 쿼리가 들어있는 함수들은 routes.py파일들에서 호출된다.
@main_bp.route('/')
def homepage():
new_book_list = db.get_newbooks()
return render_template('main/homepage.html', new_books = new_book_list)
여기서 new_book_list는 위에서 얘기한 dictionary들의 list가 된다.
이 render_template를 통해 html파일을 실행하고 인자도 전달된다.
1-5. html 파일
이 인자는 html파일 내부에서
2. 웹요청 처리와 블루프린트
'auth' 관련 기능을 예시로 설명한다.
2-1. 블루프린트
auth_bp라는 변수에는 Blueprint라는 클래스의 객체가 저장된다.
이 객체는 auth기능과 관련된 모든 URL(라우팅) 규칙을 담는 컨테이너의 역할을 한다.
첫 번째 인자로 str을 받는데, 이는 나중에 url_for등을 사용할 때 이 blueprint를 찾기위한 이름이 된다.
뒤의 __name__은 module타입으로 현재 파일의 위치 정보를 담고 있다. 나중에 이 blueprint와 관련된 template나 static폴더의 위치를 자동 계산한다.
url_prefix는 이 blueprint(즉 auth_bp)안에 있는 모든 URL경로 앞에 '/auth'라는 주소를 붙인다.
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
2-2. __init__.py 선언
이 블루프린트들은 __init__.py 파일에서 등록을 해주어야한다.
from .main import routes as main_routes
from .auth import routes as auth_routes
from .mypage import routes as mypage_routes
app.register_blueprint(main_routes.main_bp)
app.register_blueprint(auth_routes.auth_bp)
app.register_blueprint(mypage_routes.mypage_bp)
2-3. routes.py
방금 auth_bp 변수는 라우팅 규칙을 담는다고 했는데,
아래 코드는 이 규칙을 추가하는 역할을 한다.
@auth_bp.route()는 바로 밑에 정의된 함수를 실행시킨다.
첫 인자인 '/login'은 url_prefix뒤에 붙는 세부 주소이다. 따라서 최종 로그인 페이지 주소는 .../auth/login이 된다.
뒤에 methods는 이 url에서 처리 가능한 요청의 종류를 정한다.
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
...
return render_template('auth/login.html')
@auth_bp.route('/logout')
def logout():
...
return redirect(url_for('main.homepage'))
url_for()는 해당 url을 자동으로 생성해준다.
아래처럼 하드코딩된 경로를 사용하지 않아도 된다.
<a href="/auth/login">
인자는 '.'으로 구분되는데, 앞부분은 위에서 Blueprint의 첫 인자(str)이고
뒷부분은 함수 이름이다.
이 함수 이름은 routes파일들에서 @바로 밑에 나오는 함수를 의미한다.
위의 1-4의 코드를 참고하면 된다.
#1-4 코드
@main_bp.route('/')
def homepage():
결국 homepage()함수의 render_template()를 통해 최종적으로 html파일이 실행되게 된다.
3. css 및 js파일 연동
아래 코드에서도 url_for이 사용되는 것을 볼 수 있다.
다만 약간 기능이 달라지는데, 첫 인자인 'static'은 url_for의 예약어로,
static폴더를 찾으라는 의미이고 다음 인자에서 상세 경로가 주어진다.

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/slide.js') }}"></script>
4. 프로그램 전체 흐름
4-1. create_app() 실행
테스트환경에서 디버그 모드로 실행할 떄는 run.py를 실행하지만 run.py내부적으로도 create_app()이 실행된다.
실제 deploy 상태에서는 run.py가 아닌 직접 create_app()을 실행해야한다.
create_app()에서는 블루프린트 등록을 하고,
내부적으로 모든 url규칙(@...route(...))을 모아서 거대한 일종의 url map을 만든다.
4-2. 사용자의 접속
사용자가 url을 입력해 접속한다.
http://127.0.0.1:5000/
예시로 이 주소로 입력되었다면 '/'에 대한 요청을 찾는다.
4-3. url 매칭 및 함수 실행
flask는 url map에서 main 블루프린트의 homepage()가 '/'와 연결되어 있다는 것을 파악한다.따라서 app/main/routes.py의 homepage()를 실행한다.
4-4. 렌더링
homepage()는 render_template를 사용해 html코드를 생성하고 브라우저에 응답으로 보내준다.
'프로젝트, 연구 > 도서관 관리 사이트' 카테고리의 다른 글
| [도서관 관리 사이트] 6. 마이페이지, 모든서적 페이지, 인기차트 페이지 (0) | 2025.10.24 |
|---|---|
| [도서관 관리 사이트] 5. 회원가입, 관리자페이지, 책/카테고리 수정 (0) | 2025.10.20 |
| [도서관 관리 사이트] 3. DB 입력, 메인페이지, 로그인 페이지 (2) | 2025.10.13 |
| [도서관 관리 사이트] 2. 웹페이지 설계, 프로젝트 폴더 구성 (2) | 2025.10.11 |
| [도서관 관리 사이트] 1. 기능 확인, DB구조 설계, 프레임워크 선택 (0) | 2025.10.10 |