반응형

Flask 웹 애플리케이션 배포 및 전체 개발 여정 마무리

이제 Flask로 만든 내 앱을 세상 밖으로 꺼내놓을 시간입니다.
코딩만으로는 끝나지 않는 웹 개발의 진짜 마무리,
배포의 세계로 함께 떠나볼까요?

 

 

안녕하세요! 어느덧 8일 간의 Flask 웹 개발 여정이 끝을 향해 가고 있습니다.

오늘은 정말 중요한 시간이자, 실제 서비스를 꿈꾸는 개발자라면 반드시 짚고 넘어가야 할 Flask 애플리케이션의 배포 과정을 다룹니다.

개발 환경에서만 돌아가던 코드가 운영 환경에서,

즉 ‘실제 인터넷 사용자’에게 서비스되기 위해 어떤 과정이 필요한지, 어떤 요소들을 점검해야 하는지 차근차근 살펴볼 거예요.

그리고 지난 8일 동안 우리가 배운 기술들을 돌아보며, 앞으로 어떤 방향으로 더 성장할 수 있을지도 함께 이야기해 보겠습니다.

실전 배포의 긴장감 속에서도, 마무리의 뿌듯함과 성취감을 느끼실 수 있을 거예요 😊

 

1. 개발 환경 vs 운영 환경 설정 차이 이해하기 ⚙️

웹 애플리케이션을 개발하면서 가장 흔하게 저지르는 실수 중 하나는 개발 환경운영 환경을 동일하게 다룬다는 점입니다.

개발은 말 그대로 테스트와 디버깅이 용이하게 구성되어 있지만, 운영 환경은 실제 사용자와의 만남이기 때문에 보안, 성능, 안정성 등 모든 면에서 더욱 철저하게 대비해야 합니다.

🔐 DEBUG 모드 해제와 그 중요성

개발할 때는 DEBUG=True로 설정해서 코드 수정 후 바로 반영되도록 하고, 에러가 발생하면 상세한 디버거 화면을 확인할 수 있어서 편하죠.

하지만 운영에서는 반드시 DEBUG=False로 변경해야 합니다.

이유는 간단해요.

에러 메시지를 통해 시스템 내부 구조나 경로, 변수명이 노출될 수 있기 때문이에요.

이것만으로도 보안에 심각한 구멍이 생길 수 있죠.

  • DEBUG=False 설정은 사용자에게 민감한 에러 정보를 숨겨주는 역할
  • 에러 추적은 logging 모듈을 통해 따로 처리

📦 환경 변수로 민감 정보 분리하기

운영 환경에서는 SECRET_KEYDB 비밀번호 같은 민감한 정보가 절대 코드에 직접 노출되어선 안 됩니다.

이를 위해 .env 파일을 사용하거나, 운영체제의 환경 변수에 등록해 관리하는 것이 일반적이에요.

Flask에서는 python-dotenv 같은 라이브러리를 사용하면 .env 파일을 쉽게 로드할 수 있죠.

예시 - .env 파일

SECRET_KEY=mysecretkey123
DATABASE_URL=mysql://user:password@localhost/db
FLASK_ENV=production

🛠️ 개발 DB vs 운영 DB

개발 환경에서는 SQLite 같은 간단한 파일 기반 데이터베이스를 사용하는 경우가 많지만,

운영 환경에서는 MySQL, PostgreSQL 같은 상용 또는 오픈소스 DB를 사용해야 합니다.

특히 트래픽이 많아질 경우 DB 성능이 앱의 전체 성능에 큰 영향을 끼치기 때문에,

개발 단계부터 운영 DB로의 전환을 염두에 두고 설계하는 습관이 중요해요.

📈 로그 기록과 모니터링 준비

운영 환경에서는 예기치 않은 문제를 발견하기 위해 로그 설정이 중요합니다.

Python의 logging 모듈을 활용해서 파일로 저장하거나, 콘솔/서버 스트림으로 출력하게 설정할 수 있죠.

Sentry, Datadog 같은 SaaS 기반 모니터링 도구도 함께 사용하면 더 좋습니다.

추후 확장 가능성까지 고려한다면 꼭 챙겨야 할 요소입니다.

간단한 logging 설정 예시

import logging

logging.basicConfig(
    filename='app.log',
    level=logging.INFO,
    format='%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
)

 

이처럼 운영 환경은 단순히 서버에 올리는 것 이상입니다.

전반적인 시스템의 신뢰성과 보안을 고려한 전략이 필요하죠.

다음 섹션에서는 본격적으로 배포를 위해 어떤 준비가 필요한지 살펴보겠습니다.

 

 

2. 배포를 위한 필수 설정 및 준비물 🔧

이제 운영 환경으로 옮길 준비를 본격적으로 해야겠죠.

Flask 애플리케이션을 배포하려면 몇 가지 반드시 준비해야 할 요소들이 있어요.

이 항목들은 단순히 앱을 ‘올린다’는 행위를 넘어, 안정적이고 유지보수가 가능한 형태로 운영하는 데 핵심이 됩니다.

🗂 필수 파일 구성

운영 배포를 위해 다음과 같은 파일들을 준비해두면 좋습니다.

특히 Heroku나 Railway 같은 플랫폼에서는 Procfilerequirements.txt가 필수입니다.

  • requirements.txt: 필요한 패키지 목록을 나열한 파일 (예: Flask, gunicorn 등)
  • Procfile: 실행 명령어를 담은 파일 (예: web: gunicorn app:app)
  • .env: 환경 변수 파일 (운영 시 실제 민감 정보 포함)
  • runtime.txt: 사용하는 파이썬 버전 지정 (Heroku에서 권장됨)

🌐 WSGI 서버 준비 - Gunicorn

Flask는 기본적으로 내장 개발용 서버(flask run)를 사용하지만, 운영용 서버로는 성능과 안정성이 부족해요.

그래서 WSGI(Web Server Gateway Interface)를 사용하는 서버로 전환해야 하죠.

대표적인 선택이 Gunicorn입니다.

pip install gunicorn
gunicorn app:app

 

이 명령은 현재 디렉토리에 있는 app.py 파일 안의 app 객체를 실행합니다.

Gunicorn은 멀티 스레드와 멀티 프로세스를 지원해서, 더 많은 요청을 처리할 수 있도록 해줍니다.

Windows 사용자를 위한 대안

Gunicorn은 Windows에서는 제대로 작동하지 않기 때문에 Waitress 서버를 대안으로 사용할 수 있어요.

pip install waitress
waitress-serve --port=8080 app:app

📁 정적 파일 서빙 준비

Flask도 정적 파일 서빙이 가능하지만,

실제 서비스에서는 Nginx 같은 웹 서버를 활용하는 것이 효율적이에요.

CSS, JS, 이미지 파일은 모두 Nginx가 처리하고, 동적인 라우팅 요청만 Flask로 전달되게 설정하는 게 일반적인 방식입니다.

이렇게 하면 정적 리소스의 로딩 속도도 빨라지고, Flask의 부하도 줄일 수 있어서 훨씬 쾌적한 서비스가 가능해집니다.

 

이제 기본적인 배포 준비물들을 정리했으니,

다음 단계에서는 실제로 Gunicorn과 Nginx를 활용해 애플리케이션을 배포하는 과정을 실습해볼게요!

 

 

3. Gunicorn과 Nginx를 이용한 배포 실습 🚀

이제 본격적으로 Flask 애플리케이션을 운영 환경에 배포하는 실습을 진행해보겠습니다.

이번에는 가장 널리 쓰이는 조합인 Gunicorn + Nginx 환경을 기반으로 설명할게요.

이 조합은 성능과 확장성, 안정성 측면에서 많은 Flask 프로젝트에서 사용됩니다.

🧱 Gunicorn으로 Flask 실행하기

Gunicorn은 Python WSGI 애플리케이션을 실행할 수 있는 고성능 WSGI 서버입니다.

먼저 아래와 같이 애플리케이션을 실행해보세요:

gunicorn -w 4 -b 127.0.0.1:8000 app:app

 

이 명령은 4개의 워커(worker)를 생성하여 127.0.0.1:8000 포트에서 애플리케이션을 실행합니다.

로컬에서 테스트할 경우 웹 브라우저에서 http://127.0.0.1:8000으로 접속하면 됩니다.

🌐 Nginx 설치 및 설정

이제 웹 서버인 Nginx를 설치하고 Gunicorn과 연동해봅니다.

Nginx는 클라이언트 요청을 받아 Gunicorn으로 전달해주는 프록시 역할을 수행하며, 정적 파일 서빙까지 맡을 수 있죠.

sudo apt update
sudo apt install nginx

기본 설정 예시

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        alias /home/ubuntu/yourproject/static/;
    }
}

 

위 설정은 yourdomain.com으로 들어온 요청을 127.0.0.1:8000으로 프록시 전달하고,

/static/ 경로의 파일은 Nginx가 직접 서빙합니다.

설정 후에는 다음 명령어로 Nginx를 재시작합니다:

sudo systemctl restart nginx

🔒 HTTPS 적용 개요

서비스를 인터넷에 공개한다면 HTTPS는 선택이 아닌 필수입니다.

무료 SSL 인증서인 Let’s Encrypt를 사용하면 쉽게 HTTPS를 적용할 수 있어요.

certbot을 사용하여 도메인을 인증하고 Nginx 설정을 자동으로 갱신할 수 있습니다.

다음과 같이 실행해보세요:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx

 

이 과정을 통해 인증서가 자동 설치되며, Nginx 설정도 자동으로 변경됩니다.

이제 HTTPS 기반으로 보안된 연결을 제공할 수 있습니다.

이제 로컬 개발용 서버에서 벗어나, 실제 운영 환경에서 Flask 앱을 동작시킬 준비가 끝났습니다.

다음 섹션에서는 Heroku와 같은 클라우드 플랫폼을 이용한 배포 방법을 알아볼게요!

 

 

4. 클라우드 서비스에 앱 배포하기 (Heroku 예시) ☁️

운영 환경에 배포하는 가장 쉬운 방법 중 하나는 클라우드 PaaS(Platform as a Service)를 이용하는 거예요.

오늘은 대표적인 서비스인 Heroku를 예로 들어, Flask 앱을 단계별로 배포하는 과정을 소개할게요.

Heroku 외에도 Render, Railway, PythonAnywhere, AWS EC2 등이 있지만, 초심자 입문용으로는 Heroku가 최고죠!

🧰 Heroku 배포 준비물

  • requirements.txt – 설치할 패키지 목록
  • Procfile – 실행 명령어 (예: web: gunicorn app:app)
  • runtime.txt – Python 버전 명시 (예: python-3.10.5)

🧑‍💻 Heroku CLI 설치 및 로그인

# CLI 설치 (공식 사이트 참고)
https://devcenter.heroku.com/articles/heroku-cli

# 로그인
heroku login

 

로그인을 하면 브라우저가 열리면서 인증이 완료되고, CLI에서 Heroku를 조작할 수 있게 됩니다.

📦 Flask 앱 배포하기

  1. Git 저장소 초기화
git init
git add .
git commit -m "Initial commit"
  1. Heroku 앱 생성
heroku create your-app-name
  1. Git으로 배포
git push heroku master
  1. 웹 브라우저로 접속 확인
heroku open

🔐 환경 변수 설정

SECRET_KEYDATABASE_URL 등 민감한 정보는 Heroku Dashboard나 CLI를 통해 설정할 수 있어요.

heroku config:set SECRET_KEY=mysecretvalue

 

여기까지 설정을 완료하면, Flask 앱이 Heroku를 통해 전 세계 어디서나 접근 가능한 서비스로 탈바꿈하게 됩니다!

다음 섹션에서는 운영 시 고려해야 할 보안과 성능 팁들을 소개할게요.

 

 

5. 실서비스를 위한 운영 환경 고려사항 🛡️

이제 애플리케이션이 세상에 나왔습니다. 하지만 진짜 중요한 건 지금부터예요.

서비스 운영은 단순히 앱을 “돌리는 것” 그 이상이에요.

사용자의 신뢰를 얻기 위한 보안, 성능, 확장성까지 두루 고려해야 하죠.

🔒 필수 보안 수칙

  • DEBUG=False 설정 유지 – 민감한 에러 정보 노출 방지
  • SECRET_KEY와 DB 암호는 코드에 절대 직접 작성하지 않기 – 환경 변수로 분리
  • API 요청에 JWT, OAuth, Token 기반 인증 적용하기 – 공개 API 방지

⚙️ 성능과 확장성 확보

처음에는 사용자가 적을 수 있지만, 언젠가 수천 명이 동시 접속하는 날이 올 수도 있죠.

그때를 대비해 확장성과 성능 튜닝 전략을 알아둬야 해요.

  • Gunicorn 워커 수 조절 – 서버 CPU 수와 트래픽에 따라 조정
  • DB 튜닝 및 연결 수 제한 – SQLAlchemy에서 pool_size 설정
  • Redis 캐시 도입 – 반복 쿼리 응답 속도 개선
  • CDN 적용 – 정적 파일 전송 속도 개선

🔍 다른 프레임워크와의 비교

Flask를 통해 웹 개발의 흐름을 이해했지만, 세상에는 다른 선택지도 많아요.

아래는 Flask와 자주 비교되는 프레임워크입니다:

프레임워크 특징 추천 용도
Flask 마이크로, 자유로운 구조 작은 서비스, 빠른 프로토타입
Django 풀스택, Admin 포함 중대형 프로젝트, 팀 협업
FastAPI 비동기 지원, 자동 문서화 고성능 API 서버

중요한 건, 어떤 프레임워크든 웹 서비스의 기본 개념은 비슷하다는 점이에요.

이번 과정을 통해 익힌 개념들은 다른 도구에서도 그대로 활용 가능하다는 점, 꼭 기억해주세요!

 

 

6. 전체 과정 정리 및 Q&A 🧭

어느덧 여덟 번째 날, 이번 Flask 웹 개발 여정의 마지막 단계에 도달했습니다.

그동안 배우고 실습했던 모든 내용을 정리하며, 마무리의 의미를 되새겨볼 시간이에요.

그리고 이제는 여러분이 직접 웹 개발자로서 첫 발을 내디딜 차례입니다 😊

🧩 8일간의 핵심 기술 요약

  • Flask 라우팅, 요청/응답 처리 및 템플릿 렌더링
  • Blueprint로 구조화된 웹 애플리케이션 설계
  • SQLAlchemy ORM을 활용한 데이터베이스 연동 및 CRUD
  • REST API 설계 및 JSON 형태의 응답 처리
  • Flask-WTF, Flask-Login 등 확장을 통한 기능 고도화
  • Gunicorn, Nginx, Heroku 등을 통한 배포 실습과 운영 고려사항

🙋 질의응답 & 개별 피드백

질문 있으신가요? 오늘은 자유롭게 질의응답을 진행합니다.

아직도 헷갈리는 부분이나 추가 설명이 필요한 개념이 있다면 지금 질문해 주세요.

시간이 허락된다면 간단한 데모나 그림으로도 다시 설명해드릴 수 있어요.

또한 각자 만든 프로젝트나 진행 중인 개인 작업에 대해 피드백을 받고 싶다면 언제든 공유해 주세요.

Flask를 사용한 실무적인 팁이나 코드 리뷰도 가능합니다 💬

🔮 차후 학습 방향 제안

Flask를 마스터했다고 해서 끝은 아니에요. 오히려 시작점일 수도 있어요.

아래는 다음 단계로 나아가기 위한 추천 학습 주제입니다:

  • Flask-RESTX를 활용한 API 문서 자동화 및 Swagger UI
  • JavaScript 프론트엔드 프레임워크(React, Vue 등)와의 연동 프로젝트
  • Django를 통한 풀스택 웹 앱 구축 실습

무엇보다 중요한 건, 작은 프로젝트라도 직접 만들어보는 것이에요.

CRUD 게시판, 블로그 API, 포트폴리오 웹사이트 등 본인만의 결과물을 만드는 과정이 진짜 실력이 되는 길입니다.

 

 

📝  Flask 개발 여정의 끝, 그리고 새로운 시작

여기까지 따라오신 여러분, 진심으로 고생 많으셨습니다 🙌

처음 Flask의 간단한 라우팅부터 시작해서 ORM, REST API, 배포까지, 쉽지 않은 여정을 함께 해냈다는 건 정말 대단한 일이에요.

이번 8일 과정은 단순한 코드 학습이 아닌, 웹 서비스라는 전체 흐름을 한 번 체험해보는 기회였습니다.

 

앞으로 여러분은 더 복잡한 웹 서비스도 구현할 수 있을 거예요.

그리고 이 경험은 분명히 현업 개발자나 사이드 프로젝트를 꿈꾸는 여러분에게 튼튼한 기반이 될 겁니다.

이제는 혼자서도 서버를 만들고, 클라이언트와 소통하고, 진짜로 세상에 서비스 하나를 내놓을 수 있으니까요.

그리고... 끝은 곧 시작입니다. 여기서 멈추지 말고 계속해서 나아가세요.

더 깊이 있는 백엔드 기술, 더 나은 UX를 위한 프론트엔드 기술, 클라우드 인프라까지 여러분의 세계는 점점 넓어질 거예요. 감사합니다! 💙

반응형
반응형

Flask 확장으로 게시판 프로젝트 고도화하기

단순한 게시판 웹앱에서 한 단계 더!
Flask 확장 기능으로 편리성과 보안성을 동시에 잡아보세요.

 

 

안녕하세요, Flask 웹 개발을 함께 배워가고 있는 여러분!

오늘은 우리가 지금까지 만들어온 게시판 프로젝트를 더 깔끔하고, 더 안전하게, 더 고급스럽게 만드는 방법을 소개하려 해요.

특히 Flask-WTFFlask-Login 같은 인기 확장 기능을 다루면서, 개발 효율성과 유지 보수성까지 한층 업그레이드할 수 있도록 실습 중심으로 진행할 거예요.

이제 여러분의 게시판이 진짜 '서비스다운' 모습으로 거듭날 준비를 해볼까요? 😎

 

1. Flask-WTF로 폼 처리 개선하기 ✍️

지금까지 우리는 게시글 작성 폼을 HTML로 직접 만들어 사용해왔죠.

그런데 이 방식은 반복 코드가 많고, 검증 처리도 직접 구현해야 해서 번거롭습니다.

그래서 Flask-WTF라는 확장 모듈을 사용하면 폼 관련 작업을 훨씬 더 간단하고 안전하게 처리할 수 있어요.

📌 Flask-WTF란?

Flask-WTF는 WTForms라는 폼 유효성 검사 라이브러리를 Flask에서 쉽게 사용할 수 있도록 도와주는 확장입니다.

입력 필드에 대한 클래스 기반 정의, 자동 CSRF 보호, 내장된 다양한 Validator를 지원하여 폼 처리를 안전하고 일관되게 만들어 줘요.

✔ 설치 및 설정

pip install flask-wtf

설치 후에는 Flask 설정에 SECRET_KEY를 추가해서 CSRF 보호 기능을 켜줘야 합니다.

app.config['SECRET_KEY'] = 'mysecretkey'

🛠 PostForm 클래스 만들기

게시글 작성에 필요한 폼 클래스를 다음과 같이 정의할 수 있어요.

from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField
from wtforms.validators import DataRequired, Length

class PostForm(FlaskForm):
    title = StringField('제목', validators=[DataRequired(), Length(max=100)])
    content = TextAreaField('내용', validators=[DataRequired()])

✅ Flask-WTF의 장점은?

  • HTML 입력 폼을 Python 코드로 간결하게 표현 가능
  • Validator로 유효성 검사를 쉽게 추가할 수 있음
  • CSRF 보호가 자동으로 적용되어 보안성 향상

폼 유효성 검사를 별도로 구현하지 않아도 되고, 입력값이 잘못됐을 때의 메시지도 자동 출력되기 때문에 사용자 경험도 좋아져요.

 

사실 이걸 한 번 적용해보고 나면, 앞으로는 순수 HTML 폼으로 되돌아가기 싫어질지도 몰라요. 🤭

 

 

2. 템플릿에서의 폼 렌더링과 에러 메시지 출력 💡

Flask-WTF를 도입했다면, 템플릿에서도 이제 폼 필드를 직접 출력하는 대신 WTForms의 필드 객체를 사용해 보다 동적으로 표현할 수 있어요.

게다가 오류 메시지를 자동으로 표시할 수 있어서 사용자 친화적인 폼을 아주 쉽게 구현할 수 있답니다.

🧩 기본 템플릿 구조

HTML 코드가 이렇게 바뀝니다.

form.csrf_token은 꼭 포함해야 해요. CSRF 보호를 위한 필수 요소니까요.

 


<form method="POST">{{ form.csrf_token }}
<div>
	{{ form.title.label }}
   	{{ form.title(size=40) }}
    {% for error in form.title.errors %}
       	<span style="color: red;">{{ error }}</span> 
    {% endfor %}
</div>
<div>
	{{ form.content.label }} 
    {{ form.content(rows=10, cols=50) }} 
    {% for error in form.content.errors %} 
    	<span style="color: red;">{{ error }}</span> 
    {% endfor %}
</div>
<button type="submit">작성하기</button>
</form>

기존에 우리가 직접 HTML 인풋을 만들던 방식보다 훨씬 간결하고, 유지보수도 쉬워지죠.

그리고 폼 오류 발생 시 메시지를 바로 보여줄 수 있어서 사용자 입장에서도 훨씬 직관적인 사용 경험을 제공할 수 있어요.

🔍 뷰 함수도 간단하게!

이제 뷰 함수에서는 request.form을 직접 다루는 대신 폼 인스턴스를 생성하고 검증만 하면 됩니다.

@app.route('/board/new', methods=['GET', 'POST'])
def create_post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(title=form.title.data, content=form.content.data)
        db.session.add(post)
        db.session.commit()
        return redirect(url_for('board.list'))
    return render_template('board_form.html', form=form)

이 코드는 Flask-WTF의 validate_on_submit() 메서드 덕분에 훨씬 간단하고 안전해졌어요.

그리고 form 인스턴스를 템플릿에 넘기기만 하면 끝!

🔧 에러 발생 시 확인 포인트

  • CSRF 토큰을 템플릿에 넣었는지 확인
  • FlaskForm을 상속받았는지 확인
  • SECRET_KEY 설정이 누락되지 않았는지 확인

폼 유효성 검사를 제대로 처리하면 실수로 잘못된 데이터를 넣는 경우도 줄어들고, 사용자도 시스템을 더 신뢰하게 됩니다.

개발자 입장에서도 디버깅 시간이 줄어든다는 거, 진짜 큰 장점이에요! 🙌

 

 

3. Flask-Login으로 사용자 인증 개념 익히기 🔐

이제 게시판 프로젝트가 어느 정도 완성 단계에 이르렀다면, 사용자 인증을 고려할 시점이에요.

왜냐하면, 글을 작성하거나 수정, 삭제할 수 있는 권한을 아무에게나 줄 수는 없으니까요.

바로 여기서 Flask-Login이라는 강력한 확장 기능이 등장합니다.

🔑 Flask-Login 소개

Flask-Login은 로그인 상태를 세션에 저장하고, 인증이 필요한 페이지에 접근할 때 로그인 여부를 자동으로 체크해주는 편리한 인증 도구예요.

별도의 UI는 없고, 세션 관리, 현재 사용자 확인, 데코레이터를 이용한 보호 기능에 충실합니다.

🚀 핵심 기능

  • login_user()로 로그인 처리
  • logout_user()로 로그아웃 처리
  • login_required 데코레이터로 특정 라우트 보호

그리고 현재 로그인한 사용자를 확인할 때는 current_user 객체를 사용해요.

User 모델에는 몇 가지 필수 메서드와 속성을 추가해줘야 정상 동작합니다.

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)

Flask-Login은 UserMixin 클래스를 상속하면 필요한 메서드들을 자동으로 구현해주기 때문에 아주 편리해요.

물론, 비밀번호는 반드시 해시처리를 해야겠죠?

📝 적용 시나리오

  1. User 모델을 설계하고, 로그인/회원가입 폼을 만들기
  2. 로그인 상태를 세션으로 유지하고, 필요 시 인증 검사하기
  3. 게시글 작성, 수정, 삭제 뷰에 @login_required 추가

이번 강의에서는 시간이 부족하니 직접 구현은 생략하고, 인증 시스템의 구조와 적용 포인트만 개념적으로 익히면 충분합니다.

더 자세히 배우고 싶다면 Flask-Login 공식 문서Flask 튜토리얼의 인증 챕터를 꼭 참고해보세요.

 

중요한 건, 인증은 '기능 추가' 그 이상의 가치가 있다는 거예요.

서비스의 신뢰도와 확장성을 동시에 끌어올려주는 필수 요소니까요. 😊

 

 

4. 게시판 기능 마무리 및 UI 개선 🎨

게시판 기능이 얼추 완성되었죠?

이제는 사용자 경험(UX)을 고려한 마무리 작업을 해볼 차례예요.

그동안 구현했던 CRUD 기능들이 자연스럽게 연결되도록 테스트하고, UI 개선까지 살짝 손대보는 거죠.

💅 Bootstrap으로 UI 다듬기 (선택사항)

Bootstrap은 CSS 프레임워크 중에서도 가장 보편적으로 사용되는 도구예요.

특히 테이블, 폼, 버튼 등 기본 UI 요소들을 빠르게 스타일링할 수 있어서 초보자도 쉽게 적용할 수 있습니다.


  • <table class="table table-hover"> 형태로 목록 페이지 개선
  • form-control, btn btn-primary 등으로 폼 및 버튼 꾸미기

🔁 기능 흐름 점검

다음 시나리오를 한 번 따라가 보세요.

실제 사용자가 프로젝트를 어떻게 사용할지를 기준으로 흐름을 확인하는 거예요.

  1. 새 글 작성 → 제출
  2. 목록 페이지에서 작성한 글 확인
  3. 상세 페이지에서 글 내용 조회
  4. 글 수정 → 다시 확인
  5. 글 삭제 → 목록에서 사라졌는지 확인

🧼 자잘한 버그 및 UX 개선

  • 글이 없을 때 ‘게시글이 없습니다’ 문구 표시
  • 너무 긴 제목은 text-overflow: ellipsis로 잘라내기
  • 삭제 확인 버튼에 JavaScript confirm() 사용

이런 자잘한 디테일들이 모이면, 사용자들은 “오, 이 서비스 되게 잘 만들었네?”라는 느낌을 받게 되죠.

기술력은 기본, 디테일이 완성도를 결정한다는 말, 잊지 마세요. 😉

 

 

5. 전체 기능 점검과 코드 리팩토링 ⚙️

이제 우리가 만든 게시판 프로젝트의 전체 기능을 점검하고, 코드 구조를 한번 깔끔하게 정리해볼 차례입니다.

지금까지는 각 기능을 하나씩 배우고 붙이는 데 집중했다면,

이 단계에서는 전반적인 동작 흐름코드 일관성에 신경 써야 해요.

🧪 시나리오 테스트

실제 사용자가 게시판을 사용할 상황을 가정해서 테스트해보세요.

아래와 같은 항목을 체크리스트로 삼는 것도 좋습니다.

  • 새 글 작성 후 목록 반영 확인
  • 글 상세 페이지에서 제목과 내용 확인
  • 글 수정 및 삭제 후 정상 반영 여부 확인

🧹 코드 정리 (리팩토링)

플라스크 앱의 구조가 깔끔하게 정리되어야 유지보수가 쉬워집니다.

Blueprint로 분리한 파일들을 다음처럼 정리해보세요.

/app
├── __init__.py         # 앱 생성 및 구성
├── models.py           # DB 모델
├── routes.py           # 라우터
├── forms.py            # Flask-WTF 폼 클래스
├── templates/          # HTML 템플릿들
└── static/             # 정적 파일(CSS, JS 등)

이 구조는 규모가 커질 때 유지보수를 훨씬 수월하게 해줘요.

추후 Flask 애플리케이션 팩토리 패턴을 적용하면 더 모듈화된 구조도 가능합니다.

🌐 API 엔드포인트 점검

RESTful API로 구현된 엔드포인트들이 잘 작동하는지도 꼭 확인해봅시다.

프론트엔드뿐 아니라 외부 앱에서도 이 API를 쓸 수 있게 설계한 것이니까요.

  • GET /api/posts → 게시글 목록 반환
  • POST /api/posts → 새 글 등록

만약 CORS 문제로 외부 클라이언트에서 API 호출이 안 된다면,

flask-cors 확장을 설치하고 아래처럼 설정해 주세요.

from flask_cors import CORS
CORS(app)

이제 여러분의 게시판 프로젝트는 기능, 구조, 디자인, API까지 모두 균형 잡힌 상태예요! 🎯

정말 멋지게 완성됐습니다.

 

 

6. 확장 기능과 보안 적용에 대한 심화 토론 🤔

이번 단계는 약간 자유로운 분위기에서 마무리해보는 시간이에요.

지금까지 우리가 만든 게시판을 바탕으로 앞으로 확장할 수 있는 방향이나 고급 기능에 대한 아이디어를 나눠볼게요.

💬 이런 기능도 추가해보면 어떨까요?

  • 댓글 기능: 각 게시글에 댓글을 달 수 있도록 DB와 템플릿을 확장
  • 검색 기능: 제목 또는 본문에서 키워드를 기반으로 검색
  • 페이지네이션: 게시글이 많아졌을 때 페이지 나누기
  • 파일 업로드: 이미지를 첨부하거나 업로드된 파일 관리 기능

🛡 Flask 보안 확장 소개

사용자 인증을 조금 더 제대로 구현하고 싶다면 Flask-Security 또는 Flask-User 같은 확장도 고려할 수 있어요.

회원 가입, 로그인, 비밀번호 리셋, 이메일 인증 등 흔히 필요한 기능들이 모두 포함되어 있습니다.

🙋‍♀️ 수업 마무리 및 토론 주제

이제 이 프로젝트를 마무리하면서,

다음과 같은 질문을 던져볼 수 있어요:

  • Flask 프로젝트에서 가장 어려웠던 점은 무엇인가요?
  • Flask를 활용한 다른 웹 서비스 아이디어가 있을까요?
  • 확장 기능 중 가장 유용했던 것은 무엇이었나요?

 

이런 질문들을 주제로 서로의 경험을 나누고, 앞으로 어떤 방향으로 발전시킬 수 있을지도 생각해보면 정말 좋은 학습 마무리가 될 거예요.

여기까지 따라오신 여러분, 진심으로 멋졌습니다! 👏👏👏

반응형
반응형

파이썬 REST API 개발 및 활용 완벽 가이드

웹 브라우저 말고도,
모바일 앱이나 외부 시스템에서도 우리 Flask 게시판을 사용할 수 있다면 얼마나 좋을까요?
그 해답은 바로 REST API입니다!

 

 

안녕하세요! 😊

Flask 기반 웹 게시판 프로젝트 여섯째 날입니다.

오늘은 웹 프론트엔드만이 아닌, 외부 클라이언트에서도 사용할 수 있는 REST API 개발을 함께 배워보려고 해요.

예를 들어,

우리가 만든 게시판 기능을 모바일 앱이나 다른 백엔드 서비스에서도 활용하고 싶다면 어떻게 해야 할까요?

그 해답은 바로 Flask를 이용한 RESTful API 구축이에요.

이번 시간에는 REST의 기본 개념부터 시작해 Flask에서 JSON 데이터를 주고받는 API 만들기,

그리고 게시판 CRUD API를 직접 구현해보는 실습까지 차근차근 진행할게요.

어렵지 않아요. 이미 우리가 만든 게시판 로직을 바탕으로 하니까 훨씬 수월하게 느껴질 거예요.

그럼 시작해볼까요?

 

1. RESTful API란 무엇인가요? 🤔

요즘 웹 개발에서 REST API라는 말을 자주 들어보셨을 거예요.

그만큼 백엔드 서비스를 설계할 때 꼭 알아야 할 중요한 개념이죠.

하지만 처음 들었을 땐 뭔가 복잡하고 어려워 보일 수 있어요.

그래서 이번에는 RESTful API의 핵심 개념을 쉽고 간단하게 정리해드릴게요!

REST의 핵심 개념은?

  • Resource(자원): REST는 웹의 모든 것을 자원으로 봅니다. 예를 들어 게시글(post), 사용자(user) 같은 것이죠.
  • URI(Uniform Resource Identifier): 자원을 식별하는 주소입니다. 예: /api/posts
  • HTTP 메서드: 자원에 대한 동작을 정의합니다. 예: GET(조회), POST(생성), PUT/PATCH(수정), DELETE(삭제)

REST API는 왜 이렇게 인기가 많을까요?

REST API가 널리 쓰이는 이유는 간단해요.

간결하고 직관적인 구조 덕분이죠.

복잡한 규약 없이 HTTP의 기본 동작만으로 다양한 클라이언트와 쉽게 통신할 수 있으니까요.

또한, REST API는 다음과 같은 특징들을 가지고 있어요:

  1. 🎯 Stateless(무상태성): 각 요청은 독립적이며, 서버는 이전 요청의 상태를 저장하지 않아요.
  2. 🔄 Cacheable: 응답은 캐싱이 가능하므로 성능을 높일 수 있어요.
  3. 🧩 Uniform Interface: 표준화된 인터페이스 덕분에 다양한 플랫폼에서 사용할 수 있어요.

RESTful API 설계시 고려사항은? 🧐

RESTful하게 API를 설계하기 위해 지켜야 할 몇 가지 규칙이 있어요.

특히 초보자들이 자주 놓치는 부분들을 짚어볼게요.

  • URL은 복수형 명사로: 예를 들어 게시글이면 /api/posts와 같이 작성하는 것이 좋습니다.
  • HTTP 상태 코드 정확히 사용: 예를 들어, 성공은 200, 생성은 201, 오류는 400 또는 404 등으로 클라이언트에게 명확히 알려줘야 해요.
  • JSON 응답은 일관성 있게: 예를 들어 항상 {"id": 1, "title": "...", "content": "..."}와 같은 형식 유지

REST API는 단순히 엔드포인트만 만든다고 되는 게 아니라,

일관성과 예측 가능성을 고려해 설계해야 클라이언트가 편하게 쓸 수 있어요.

이게 바로 진짜 백엔드 개발자의 센스겠죠? 😉

 

 

2. Flask에서 REST API 만들기 🔧

자, 이제 본격적으로 Flask로 REST API를 만들어볼까요?

사실 Flask에서는 별도의 라이브러리 없이도 API를 쉽게 만들 수 있어요.

jsonify() 함수와 request.get_json() 메서드만 잘 활용하면 되거든요.

기본 API 예제

가장 기본적인 API는 이렇습니다.

“/api/hello”에 GET 요청을 보내면 JSON 형식으로 인사 메시지를 돌려주는 간단한 코드예요.

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/api/hello", methods=["GET"])
def hello_api():
    return jsonify(message="안녕하세요! 여기는 Flask REST API입니다.")

 

이렇게 간단한 코드만으로도 API가 완성돼요.

응답은 자동으로 Content-Type: application/json을 포함하므로 별도 설정도 필요 없답니다.

POST 요청 처리 - 클라이언트로부터 JSON 받기

POST 요청은 클라이언트가 서버에 데이터를 보낼 때 사용합니다.

아래처럼 request.get_json()으로 JSON 데이터를 받아 처리할 수 있어요.

from flask import request

@app.route("/api/echo", methods=["POST"])
def echo_api():
    data = request.get_json()
    name = data.get("name", "익명")
    return jsonify(message=f"{name}님, 안녕하세요!")

 

  • request.get_json(): JSON 데이터를 받아서 Python dict로 변환해줘요.
  • jsonify(): dict를 JSON으로 변환해서 응답해줍니다.

 

💡 확장 라이브러리는 쓸까 말까?

Flask는 기본 기능만으로도 API 작성이 가능하지만, 더 복잡한 구조나 반복을 줄이려면 Flask-RESTful 같은 확장을 쓸 수도 있어요.

하지만 지금은 기초 개념을 제대로 익히는 것이 중요하므로, 확장 없이 직접 구현해볼게요.

 

즉, JSON 처리에 필요한 최소한의 도구만으로도 강력한 API를 만들 수 있다는 점!

Flask의 가장 큰 매력이자 초보자에게 추천하는 이유이기도 해요.

 

 

3. JSON 응답 및 요청 처리 방식 📦

REST API에서 데이터를 주고받을 때 가장 흔히 사용하는 형식이 바로 JSON입니다.

Flask에서는 JSON 처리가 매우 간단하면서도 직관적이에요.

이번엔 JSON 응답을 어떻게 만들고, 클라이언트의 JSON 요청 데이터를 어떻게 처리하는지를 정리해볼게요.

1️⃣ JSON 응답 만들기

HTML을 반환하던 일반 웹 뷰와 달리,

API에서는 Python의 딕셔너리 데이터를 JSON 문자열로 변환해서 반환합니다.

Flask에서는 jsonify()를 사용하면 딕셔너리를 자동으로 JSON 형식으로 바꿔주고,

Content-Typeapplication/json으로 지정해줍니다.

from flask import jsonify

@app.route("/api/greet")
def greet():
    return jsonify({
        "status": "success",
        "message": "API가 정상 작동 중입니다."
    })
  • jsonify()는 자동으로 application/json MIME 타입과 200 OK 상태 코드를 설정합니다.

2️⃣ 클라이언트 JSON 요청 처리하기

클라이언트가 보내는 JSON 데이터를 받으려면 request.get_json() 메서드를 사용합니다.

이때 Content-Typeapplication/json으로 설정되어 있어야 해요.

from flask import request

@app.route("/api/submit", methods=["POST"])
def submit_data():
    data = request.get_json()
    name = data.get("name")
    age = data.get("age")
    if not name or not age:
        return jsonify(error="Missing fields"), 400
    return jsonify(message=f"{name}님({age}세), 데이터가 잘 수신되었습니다.")

 

get_json()을 통해 클라이언트의 JSON 요청을 dict로 파싱하고, 데이터 유효성 검사까지 함께 처리할 수 있어요.

3️⃣ 잘못된 요청 처리하기

API는 언제나 올바르지 않은 요청을 고려해야 합니다.

예를 들어

JSON 필드가 빠졌거나 잘못된 값이 들어오면, 클라이언트에게 명확한 메시지와 함께 400 Bad Request를 반환해야 하죠.

 

이런 식으로 API의 응답 일관성을 유지하는 것이 사용자 경험을 높이는 핵심 포인트입니다!

🔓 참고: CORS(Cross-Origin Resource Sharing)

프론트엔드가 다른 도메인(예: React 앱)에서 API를 호출할 경우 CORS 문제가 발생할 수 있어요.

이럴 땐 Flask-CORS 확장을 사용하면 아주 쉽게 해결할 수 있습니다.

# 설치
pip install flask-cors

# 사용 예
from flask_cors import CORS
app = Flask(__name__)
CORS(app)

 

 

4. 게시판 CRUD API 설계 및 구현 📝

이제 본격적으로 게시판 기능을 REST API 형태로 구현해볼 차례입니다.

이전까지는 HTML 페이지를 렌더링해 사용자에게 보여주는 방식이었다면,

이번에는 데이터를 JSON으로 주고받는 API 방식으로 확장합니다.

같은 기능이지만 'API형 백엔드'로 구현한다는 점에서 의미가 커요!

📌 API 엔드포인트 설계

Method URL 설명
POST /api/posts 게시글 생성
GET /api/posts 게시글 목록 조회
GET /api/posts/<id> 게시글 상세 조회
PUT /api/posts/<id> 게시글 수정
DELETE /api/posts/<id> 게시글 삭제

🔨 주요 기능별 구현 예제

1. 게시글 생성 - POST /api/posts

@app.route("/api/posts", methods=["POST"])
def create_post():
    data = request.get_json()
    title = data.get("title")
    content = data.get("content")
    if not title or not content:
        return jsonify(error="필수 입력값 누락"), 400
    new_post = Post(title=title, content=content)
    db.session.add(new_post)
    db.session.commit()
    return jsonify(post_id=new_post.id), 201

2. 게시글 목록 - GET /api/posts

@app.route("/api/posts", methods=["GET"])
def get_posts():
    posts = Post.query.order_by(Post.id.desc()).all()
    result = [post.to_dict() for post in posts]
    return jsonify(posts=result)

 

to_dict()는 모델 클래스에 미리 정의해두어야 합니다.

예: return {"id": self.id, "title": self.title, ...}

3. 게시글 상세조회 - GET /api/posts/<id>

@app.route("/api/posts/<int:post_id>", methods=["GET"])
def get_post(post_id):
    post = Post.query.get(post_id)
    if not post:
        return jsonify(error="존재하지 않는 게시글입니다."), 404
    return jsonify(post=post.to_dict())

4. 게시글 수정 - PUT /api/posts/<id>

@app.route("/api/posts/<int:post_id>", methods=["PUT"])
def update_post(post_id):
    post = Post.query.get(post_id)
    if not post:
        return jsonify(error="해당 게시글 없음"), 404
    data = request.get_json()
    post.title = data.get("title", post.title)
    post.content = data.get("content", post.content)
    db.session.commit()
    return jsonify(message="수정 완료", post=post.to_dict())

5. 게시글 삭제 - DELETE /api/posts/<id>

@app.route("/api/posts/<int:post_id>", methods=["DELETE"])
def delete_post(post_id):
    post = Post.query.get(post_id)
    if not post:
        return jsonify(error="해당 게시글 없음"), 404
    db.session.delete(post)
    db.session.commit()
    return jsonify(message="삭제 완료")

 

 

5. 실습: API 테스트와 사용 예시 🧪

API를 만들었으면 이제는 잘 작동하는지 테스트해봐야겠죠?

우리가 만든 REST API는 브라우저에서는 GET 요청 정도만 직접 확인할 수 있어요.

하지만 POST, PUT, DELETE 같은 요청은 curl이나 Postman 같은 도구로 테스트하는 게 일반적입니다.

🖥 curl 명령어로 API 테스트

  • GET 요청 - 게시글 목록 확인:
    curl -X GET http://localhost:5000/api/posts
  •  
  • POST 요청 - 새 게시글 생성:
    curl -X POST -H "Content-Type: application/json" -d '{"title":"첫 글", "content":"안녕하세요"}' http://localhost:5000/api/posts

🧪 Postman 사용 팁

Postman은 GUI 기반의 API 테스트 도구예요.

HTTP 메서드 선택, 요청 바디 JSON 입력, 응답 확인을 아주 편리하게 할 수 있습니다.

  1. Postman 실행 후 새 요청(Request) 생성
  2. Method: POST, URL: http://localhost:5000/api/posts
  3. Body 탭 → raw → JSON 선택 후 아래 내용 입력: 
  4.  
  5. { "title": "Postman 테스트", "content": "이건 Postman에서 보낸 글이에요." }
  6. Send 버튼 클릭 → 응답 확인!

✅ 예외 케이스 테스트하기

  • 존재하지 않는 게시글을 조회:
    GET /api/posts/99999 → 404 응답 확인
  •  
  • 필수 필드 누락 POST 요청 보내기 → 400 Bad Request 응답 확인

테스트를 반복하면서 우리 API가 얼마나 잘 짜여져 있는지 실감하게 되실 거예요.

오류 메시지도 일관성 있게 만들었다면 더더욱 멋지죠! 😉

 

 

6. 다양한 클라이언트와의 연동 시나리오 📱

지금까지 우리는 Flask 기반 게시판 API를 설계하고 구현하고, 테스트까지 마쳤어요.

이제는 다양한 클라이언트에서 이 API를 어떻게 활용할 수 있을지에 대해 살펴보는 시간입니다.

단순히 웹 브라우저뿐 아니라 모바일 앱, 프론트엔드 자바스크립트, 다른 백엔드 서비스 등과 연동되는 시나리오를 떠올려볼 수 있어요.

🧩 JavaScript에서 AJAX로 API 호출

가장 흔한 연동 방식은 웹 페이지에서 자바스크립트를 이용해 AJAX 방식으로 API를 호출하는 거예요.

예를 들어, HTML 페이지에서 아래처럼 Javascript의 fetch API를 사용할 수 있죠.

fetch("/api/posts")
  .then(response => response.json())
  .then(data => {
    console.log("게시글 목록:", data.posts);
  });

 

이렇게 하면 서버에서 JSON으로 반환한 게시글 목록을 자바스크립트에서 받아와 자유롭게 화면에 뿌릴 수 있어요.

📱 Flutter, React Native 같은 모바일 앱에서 연동

모바일 앱도 마찬가지예요.

백엔드에서 제공한 REST API를 HTTP 통신 모듈 (예: Flutter의 http 패키지, React Native의 axios)로 호출하면 앱에서도 동일하게 게시글을 CRUD할 수 있답니다.

  • Flutter에서는 http.post(), http.get()으로 JSON 데이터를 보내고 받아요.
  • React Native에서는 axios.post(), axios.get() 방식으로 쉽게 연동 가능해요.

🔗 다른 백엔드 시스템과의 연동

우리가 만든 Flask API는 마이크로서비스 구조에서도 활용할 수 있어요.

예를 들어,

사용자 인증은 Django가 담당하고, 게시판 기능은 Flask가 담당하는 식으로 서비스별 역할을 분리해서 통신하는 구조를 만들 수도 있어요.

🚀 실전 팁

  1. API 응답 형식은 항상 일관되게 유지하세요. (예: {"status": "success", "data": ...})
  2. 클라이언트가 다양한 환경에서 호출하는 만큼, CORS 설정은 반드시 고려해야 해요.
  3. API 문서화도 중요합니다! Swagger UI 또는 Postman Collection 등 활용해보세요.

 

이제 우리가 만든 Flask 백엔드는 웹, 앱, 서버 어디서든 활용 가능한 멋진 API 서비스가 되었어요.

여기까지 잘 따라오셨다면 이미 여러분은 초보 탈출 성공! 🎉

 

 

마무리 ✨

이번 여섯째 날 학습에서는 우리가 만든 게시판 웹 애플리케이션을 RESTful API로 확장하는 방법을 익혔습니다.

단순히 기능을 구현하는 것에서 한 걸음 더 나아가, 다양한 클라이언트와 연동 가능한 백엔드 서비스로 발전시키는 데 성공했어요.

REST API의 핵심 개념부터 Flask에서의 실제 구현, JSON 데이터 처리 방식, 그리고 Postman과 curl을 통한 실전 테스트까지 모든 과정을 실습하며 직접 체험해보셨을 텐데요, 어떠셨나요?

좀 더 현업 백엔드 개발자처럼 느껴지지 않으셨나요?

 

이제 여러분의 Flask 웹 서비스는 단지 브라우저에서만 동작하는 게 아니라, 앱, JS 프론트, 외부 시스템 등 어디에서든 자유롭게 사용할 수 있는 API 플랫폼이 된 거예요.

다음 시간에는 이 API를 어떻게 응용할 수 있을지, 또 성능 향상이나 인증 같은 고급 기능도 배워보면 좋겠죠?

 

혹시 아직 익숙하지 않은 부분이 있다면, 실습한 코드를 천천히 다시 보면서 정리해보세요.

반복이 최고의 선생님이니까요 😊

다음 단계에서 또 만나요!

반응형
반응형

파이썬과 Flask로 만드는 게시판 CRUD 완벽 가이드 💻🛠️

게시글을 웹에서 직접 작성하고 수정하고 삭제까지?
Flask와 SQLAlchemy만 있으면 가능합니다!
이 글 하나면 게시판 CRUD 구현은 완전 정복할 수 있어요.

 

 

안녕하세요, 여러분 😊

오늘은 Flask 웹 애플리케이션에서 가장 많이 사용되는 기능 중 하나인 CRUD(Create, Read, Update, Delete)를 직접 구현해볼 거예요.

단순히 이론 설명에서 그치는 게 아니라, 실제 웹 브라우저에서 게시글을 작성하고 목록을 보고, 수정하거나 삭제하는 완전한 게시판 시스템을 만들 거예요.

이 과정을 통해 Flask와 ORM(SQLAlchemy)의 활용 방법을 보다 실제적인 방식으로 배워보게 될 거예요.

기초부터 차근차근, 코드 한 줄 한 줄 이해하며 따라올 수 있게 구성했으니, 초보자도 걱정 말고 끝까지 함께 해봐요! 😉

 

1. 게시글 작성 기능 구현 (Create 기능) 📝

웹 게시판에서 가장 먼저 구현할 기능은 게시글 작성입니다.

사용자가 직접 제목과 내용을 입력하고 저장 버튼을 누르면, 해당 내용이 데이터베이스에 저장되고 목록이나 상세 페이지로 이동하게 만들 거예요.

우선 기본적인 흐름을 코드와 함께 살펴볼게요.

① 글 작성 폼 구현

`/board/new` 경로로 GET 요청 시 사용자에게 제목과 내용 입력란을 보여주는 HTML 폼을 렌더링합니다.

아래는 템플릿 예시입니다:

<form method="POST">
  <label>제목</label><br>
  <input type="text" name="title"><br>
  <label>내용</label><br>
  <textarea name="content"></textarea><br>
  <button type="submit">작성하기</button>
</form>

 

CSRF 방지와 보안은 이후 단계에서 `Flask-WTF` 같은 라이브러리를 통해 보완할 예정입니다.

지금은 기본적인 기능 흐름을 먼저 구현해보는 데 집중할게요!

② POST 요청 처리 및 DB 저장

사용자가 작성한 제목과 내용을 받아 `Post` 모델을 통해 DB에 저장합니다.

아래는 Flask 라우트 코드 예시예요:

@app.route('/board/new', methods=['GET', 'POST'])
def create_post():
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        if not title or not content:
            flash('제목과 내용을 모두 입력해주세요.')
            return redirect(url_for('create_post'))

        post = Post(title=title, content=content)
        db.session.add(post)
        db.session.commit()

        flash('게시글이 작성되었습니다.')
        return redirect(url_for('post_detail', post_id=post.id))

    return render_template('create_post.html')

③ 피드백과 리다이렉트

작성 후에는 목록 페이지 또는 상세 페이지로 이동하며 flash를 통해 사용자에게 피드백 메시지를 전달할 수 있습니다.

템플릿에서 아래와 같이 메시지를 출력할 수 있어요:

{% with messages = get_flashed_messages() %}
  {% if messages %}
    <ul>
    {% for message in messages %}
      <li>{{ message }}</li>
    {% endfor %}
    </ul>
  {% endif %}
{% endwith %}

🧪 실습 포인트

  • 제목 또는 내용을 비워서 제출했을 때 적절히 에러 처리가 되는지 확인해보세요.
  • 글 작성 후 DB에 제대로 저장되었는지 SQLAlchemy로 직접 쿼리하거나 목록 페이지에서 확인해보세요.
  • 작성 후 이동된 페이지에서 flash 메시지가 출력되는지 확인해보세요.

여기까지 구현하면 웹을 통해 실제로 글을 작성하고, 그것이 DB에 저장되는 전체 흐름을 직접 체험해볼 수 있어요.

다음은 작성된 글들을 조회해보는 기능, 목록 페이지로 넘어가볼게요!

 

 

2. 게시글 목록 조회 페이지 구현 (Read - 목록) 📋

게시판의 중심이 되는 페이지는 바로 목록 페이지입니다.

작성된 게시글들을 사용자에게 보여주는 역할을 하며, 각 게시글의 제목을 클릭하면 상세 페이지로 이동할 수 있어야 해요.

오늘은 이 목록 페이지를 Flask와 SQLAlchemy로 어떻게 구성할 수 있는지 하나씩 살펴보겠습니다.

① 목록 라우트 구현

/board 경로에서 모든 게시글을 조회할 수 있도록 라우트를 구현합니다.

작성일자를 기준으로 내림차순 정렬해 가장 최신 글이 위로 오도록 할 거예요.

@app.route('/board')
def post_list():
    posts = Post.query.order_by(Post.created_at.desc()).all()
    return render_template('post_list.html', posts=posts)

② 템플릿에서 게시글 목록 출력

게시글 데이터를 HTML에서 반복문을 통해 출력합니다.

게시글 제목을 클릭하면 상세 페이지로 이동하도록 링크를 걸어주세요.

<h2>게시글 목록</h2>
<ul>
  {% for post in posts %}
    <li>
      <a href="{{ url_for('post_detail', post_id=post.id) }}">{{ post.title }}</a>
      ({{ post.created_at.strftime('%Y-%m-%d %H:%M') }})
    </li>
  {% else %}
    <li>작성된 게시글이 없습니다.</li>
  {% endfor %}
</ul>

 

작성일이 보이도록 strftime을 활용해 날짜 포맷을 지정하는 것도 사용자 편의에 도움이 돼요.

③ (선택) 페이지네이션 기능 소개

글이 많아졌을 경우 모든 글을 한 페이지에 보여주는 것은 비효율적이에요.

이럴 땐 페이지네이션을 도입할 수 있습니다.

Flask-SQLAlchemy에서는 아래와 같이 페이지당 몇 개의 게시글을 보여줄지 설정할 수 있어요:

@app.route('/board')
def post_list():
    page = request.args.get('page', 1, type=int)
    posts = Post.query.order_by(Post.created_at.desc()).paginate(page=page, per_page=10)
    return render_template('post_list.html', posts=posts.items, pagination=posts)

 

실습에서는 구현하지 않아도 되지만, 프로젝트가 커질 경우 꼭 필요한 기능이에요.

Flask-Paginate 확장도 한 번 찾아보세요!

🧪 실습 포인트

  • 게시글 여러 개를 작성한 뒤, 최신 순으로 잘 정렬되는지 확인해보세요.
  • 게시글 제목을 클릭했을 때 해당 글의 상세 페이지로 잘 이동되는지 확인해보세요.
  • 아무 글도 없을 때 ‘게시글이 없습니다’ 문구가 표시되는지도 테스트해보세요.

이제 목록 페이지도 완성되었네요!

다음은 하나의 게시글을 눌렀을 때 나오는 상세 보기와 수정 기능을 구현해볼 차례입니다. 💪

 

 

3. 게시글 상세 보기 및 수정 기능 구현 (Read/Update) ✏️

게시글 목록에서 사용자가 특정 게시글을 클릭했을 때, 그 게시글의 내용을 보여주는 상세 보기 페이지와, 이후 수정할 수 있는 기능까지 구현해볼 거예요.

이 단계에서는 동적 라우팅, 데이터 조회, 그리고 POST 기반 수정 처리를 중심으로 배워보겠습니다.

① 게시글 상세 보기 페이지 구현

사용자가 게시글 제목을 클릭하면 /board/<post_id> 경로로 이동하도록 구현합니다.

이때 post_id를 기준으로 해당 게시글을 데이터베이스에서 조회해 보여줍니다.

@app.route('/board/<int:post_id>')
def post_detail(post_id):
    post = Post.query.get_or_404(post_id)
    return render_template('post_detail.html', post=post)

 

get_or_404()는 ID에 해당하는 데이터가 없을 경우 자동으로 404 에러를 반환해주기 때문에 안전한 처리 방식입니다.

② 수정 폼 페이지 구현

게시글 상세 페이지에서 ‘수정’ 버튼을 누르면 /board/<post_id>/edit 경로로 이동합니다.

이 경로에서는 기존 게시글 데이터를 폼의 초기값으로 미리 넣어 보여줍니다.

@app.route('/board/<int:post_id>/edit', methods=['GET', 'POST'])
def edit_post(post_id):
    post = Post.query.get_or_404(post_id)
    if request.method == 'POST':
        post.title = request.form['title']
        post.content = request.form['content']

        if not post.title or not post.content:
            flash('빈 칸 없이 입력해주세요.')
            return redirect(url_for('edit_post', post_id=post.id))

        db.session.commit()
        flash('게시글이 수정되었습니다.')
        return redirect(url_for('post_detail', post_id=post.id))

    return render_template('edit_post.html', post=post)

 

POST 요청 시 사용자가 입력한 값으로 기존 객체의 속성을 업데이트하고, db.session.commit()으로 저장합니다.

③ 수정 폼 템플릿 예시

<form method="POST">
  <label>제목</label><br>
  <input type="text" name="title" value="{{ post.title }}"><br>
  <label>내용</label><br>
  <textarea name="content">{{ post.content }}</textarea><br>
  <button type="submit">수정하기</button>
</form>

🧪 실습 포인트

  • 존재하지 않는 게시글 ID로 상세 페이지나 수정 페이지에 접근했을 때 404 오류가 잘 출력되는지 확인해보세요.
  • 수정 후 변경 사항이 목록 페이지나 상세 페이지에 즉시 반영되는지 확인해보세요.
  • 빈 입력값에 대한 처리와 사용자 피드백 메시지가 적절히 작동하는지 체크해보세요.

게시글 수정까지 완료했으니, 이제 남은 마지막 핵심 기능은 삭제입니다!

다음 단계에서는 게시글 삭제 처리 및 후속 처리까지 깔끔하게 구현해볼게요.

 

 

4. 게시글 삭제 기능 구현 (Delete) 🗑️

이제 게시글을 삭제하는 기능을 구현해볼 차례예요.

사용자 인터페이스에서 삭제 버튼을 클릭하면 해당 게시글이 실제로 데이터베이스에서 제거되고, 목록 페이지로 되돌아가게 만들 거예요.

삭제 전 확인 메시지를 띄우는 방법도 함께 알아봅시다.

① 삭제 버튼 추가하기

게시글 상세 페이지나 수정 페이지에서 삭제 버튼을 추가해 사용자가 클릭할 수 있도록 합니다.

아래는 HTML 폼을 사용한 간단한 예시예요:

<form method="POST" action="{{ url_for('delete_post', post_id=post.id) }}" 
      onsubmit="return confirm('정말 삭제하시겠습니까?');">
  <button type="submit">삭제하기</button>
</form>

 

자바스크립트의 confirm() 함수로 간단한 삭제 확인창도 띄워줍니다.

이렇게 하면 실수로 삭제하는 것을 방지할 수 있어요.

② Flask 라우트에서 삭제 처리

삭제 처리는 POST 방식으로 요청을 받아 처리하는 것이 일반적입니다.

아래는 Flask에서 삭제를 처리하는 라우트 예시입니다.

@app.route('/board/<int:post_id>/delete', methods=['POST'])
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    db.session.delete(post)
    db.session.commit()
    flash('게시글이 삭제되었습니다.')
    return redirect(url_for('post_list'))

 

get_or_404()를 통해 유효하지 않은 접근은 방지하고, 삭제 후에는 목록 페이지로 리다이렉트하며 플래시 메시지로 피드백을 줍니다.

③ 삭제 후 상태 확인

삭제가 완료되면 목록 페이지에서 해당 글이 사라져야 하고,

삭제된 게시글의 상세 주소로 접근할 경우 404 오류가 발생해야 해요.

이를 통해 삭제가 확실히 이루어졌는지 확인할 수 있습니다.

🧪 실습 포인트

  • 게시글 삭제 시 confirm 창이 잘 뜨는지 확인해보세요.
  • 삭제 후 목록 페이지에서 해당 글이 사라지는지 확인해보세요.
  • 삭제된 게시글 URL에 다시 접근했을 때 404 페이지가 나오는지도 꼭 확인해보세요.

이제 CRUD의 마지막 조각까지 완성되었습니다!

다음 단계에서는 전체 흐름을 다시 정리하고, CRUD를 어떻게 확장할 수 있을지에 대한 인사이트도 함께 나눠볼게요. 😊

 

 

5. CRUD 전체 사이클 정리 및 테스트 💡

지금까지 우리는 Flask와 SQLAlchemy를 활용해 게시판 CRUD 기능을 하나하나 구현해봤어요.

작성(Create), 조회(Read), 수정(Update), 삭제(Delete)까지 모든 사이클을 직접 경험하면서 웹 애플리케이션의 기본기를 탄탄하게 익혔습니다.

이 섹션에서는 전체 흐름을 다시 정리해보고, 실습 시 꼭 확인해야 할 테스트 항목들도 체크해볼게요.

① CRUD 사이클 요약 정리

기능 라우팅 설명
작성 (Create) /board/new 폼을 통해 게시글 생성, DB에 저장
조회 (Read - 목록) /board 모든 게시글을 리스트로 조회
조회 (Read - 상세) /board/<id> 단일 게시글을 ID로 조회
수정 (Update) /board/<id>/edit 기존 글을 수정하여 업데이트
삭제 (Delete) /board/<id>/delete 해당 게시글을 DB에서 삭제

② 전체 기능 테스트 체크리스트 ✅

  • 글 작성 시 제목과 내용이 비어 있으면 경고 메시지가 표시되는가?
  • 목록에서 최신 글이 가장 위에 오는가?
  • 상세 페이지에서 제목, 내용, 작성 시간이 제대로 보이는가?
  • 수정 시 기존 내용이 폼에 미리 채워지고, 수정 후 정상 반영되는가?
  • 삭제 후 목록에서 글이 사라지고, 삭제된 글 URL 접근 시 404가 나오는가?

③ 다음 단계 미리 보기 👀

CRUD 기능은 웹 애플리케이션의 핵심 기초라고 할 수 있어요.

이후에는 이 기능들을 REST API 형태로 제공하거나, JavaScript를 활용해 비동기로 처리하는 등 다양한 확장으로 이어질 수 있어요. 예를 들어:

  • 게시판을 API 형태로 만들어 React, Vue 같은 프론트엔드 프레임워크와 연동하기
  • JWT 로그인 기능과 결합해 작성자 인증/권한 부여 기능 추가하기
  • 댓글 기능, 파일 첨부 기능 등 게시판 고도화

이번 CRUD 구현이 단순한 끝이 아니라, 앞으로 나아갈 가능성의 출발점이라는 걸 꼭 기억해 주세요!

 

 

6. 마무리 및 다음 단계 안내 🚀

여기까지 따라오신 여러분 정말 수고 많으셨습니다! 👏

Flask와 SQLAlchemy를 사용한 게시판 CRUD 기능 구현을 하나하나 직접 해보며, 웹 애플리케이션 개발의 핵심 흐름을 완전히 익히셨을 거예요.

처음에는 생소했던 라우팅, 폼 데이터 처리, 데이터베이스 모델, 커밋과 쿼리 등 다양한 개념이 이제는 자연스럽게 느껴지실 겁니다.

이 CRUD 구현 경험은 이후의 모든 웹 개발 여정에 있어서 든든한 뼈대가 되어줄 거예요.

 

이번 실습을 통해 익힌 기술은 단순한 기능 구현을 넘어서, 실제 서비스를 만들고 유지보수하는 데에도 큰 도움이 됩니다.

 

그리고 여기서 끝이 아니에요!

다음 단계에서는 이 CRUD 기능들을 RESTful API로 전환하고, 프론트엔드와 연결하거나, 인증 기능을 넣는 방법도 배울 수 있어요.

웹 개발자로서 한 단계 더 도약할 수 있는 기반이 다져진 거죠. 😎

 

꼭 한 번 CRUD 기능을 자신만의 프로젝트에 적용해보세요.

예를 들어,

  • 나만의 블로그 만들기
  • 간단한 TODO 앱이나 일기장 만들기
  • Flask와 React를 연동한 게시판 프로젝트 도전하기

앞으로도 꾸준히 연습하고 발전해 나가면, 어떤 웹 서비스도 직접 만들 수 있게 될 거예요.

우리는 이제 시작입니다! 😄

반응형
반응형

파이썬 ORM과 데이터베이스 연동 (SQLAlchemy)

데이터를 손쉽게 저장하고 꺼낼 수 있다면 얼마나 편할까요?
SQL 없이 파이썬 객체만으로 DB를 다룰 수 있는 방법,
지금 바로 알아보세요!

 

 

안녕하세요, 여러분!

Flask 웹 개발의 핵심 기능 중 하나는 바로 데이터베이스 연동이죠.

특히 게시판, 블로그, 사용자 시스템 등에서 데이터를 저장하고 불러오는 기능은 필수입니다.

오늘은 ORM(Object Relational Mapping) 개념부터 Flask-SQLAlchemy를 활용한 실제 데이터베이스 연동까지, 실습 중심으로 하나씩 차근차근 배워볼 거예요.

SQLite를 사용해 복잡한 환경 설정 없이 시작하고, 직접 모델을 정의하고 테이블을 생성해보며 ORM의 편리함을 체감해보세요.

실습 예제를 따라하면서 여러분만의 데이터 저장 시스템을 만들어봅시다!

 

1. ORM과 SQLAlchemy란? 🧠

여러분은 SQL 문을 일일이 작성하며 데이터를 관리하던 경험, 있으신가요?

테이블 생성, 삽입, 조회, 수정, 삭제… 이 모든 작업을 SQL 없이 파이썬 객체만으로 할 수 있다면 얼마나 편할까요?

바로 그걸 가능하게 해주는 기술이 ORM (Object Relational Mapping)입니다.

ORM이란 무엇인가요?

ORM은 객체 지향 프로그래밍(OOP)과 관계형 데이터베이스(RDB)를 연결해주는 브릿지 역할을 합니다.

즉, 테이블 → 클래스, 레코드 → 객체로 매핑해주는 거죠.

파이썬 클래스와 객체를 통해 데이터를 조작하고 관리할 수 있어, 마치 메모리 내 객체를 다루듯 DB 작업을 수행할 수 있습니다.

 

ORM은 단순히 편리함을 넘어서, 유지보수성과 재사용성, 보안성까지 함께 높여줍니다.

  • SQL 문법을 몰라도 DB 조작이 가능해요
  • DB 변경이 생겨도 코드 수정 최소화
  • 보안상 SQL 인젝션 위험이 줄어듭니다

SQLAlchemy란?

SQLAlchemy는 파이썬에서 가장 널리 쓰이는 ORM 프레임워크입니다.

SQL을 완전히 추상화하여 객체 기반으로 DB 작업을 할 수 있게 도와주죠.

특히 다양한 DBMS(예: MySQL, PostgreSQL, SQLite, Oracle 등)를 지원하여 확장성 면에서도 매우 강력합니다.

Flask에서는 Flask-SQLAlchemy라는 확장 라이브러리를 통해 SQLAlchemy를 더 쉽고 간편하게 사용할 수 있어요.

SQLAlchemy의 핵심 특징

특징 설명
ORM + Core 지원 ORM 방식과 SQL 직접 작성 방식 모두 지원
다양한 DB 지원 SQLite, MySQL, PostgreSQL 등 거의 모든 RDBMS 사용 가능
모델 클래스 매핑 파이썬 클래스와 DB 테이블 자동 매핑
세션 기반 트랜잭션 세션을 통한 트랜잭션 관리로 안전한 작업 가능

실습에서는 SQLite를 사용해볼 거예요.

설치가 필요 없고 파일 기반으로 바로 실행되니까 입문자에게 최적이거든요!

 

2. Flask-SQLAlchemy 설정 방법 ⚙️

ORM 개념과 SQLAlchemy에 대해 이해했다면, 이제 실전입니다!

Flask 애플리케이션에서 Flask-SQLAlchemy를 설정하고 SQLite와 연결해 보겠습니다.

1️⃣ Flask-SQLAlchemy 설치하기

pip install flask flask_sqlalchemy

Flask는 이미 설치되어 있다고 가정하고, flask_sqlalchemy만 설치하면 준비 완료입니다!

2️⃣ 데이터베이스 구성 설정

Flask 앱에서 SQLAlchemy를 사용하려면, 먼저 DB URI를 설정해야 합니다.

이번 실습에서는 SQLite를 사용하므로 다음과 같은 설정이 필요합니다:

# app.py 또는 config.py 파일 내
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///board.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
  • sqlite:///board.db: 현재 프로젝트 폴더에 board.db 파일 생성
  • SQLALCHEMY_TRACK_MODIFICATIONS: 변경 추적 기능 비활성화 (경고 방지)

3️⃣ SQLAlchemy 초기화

설정을 마쳤다면 Flask 애플리케이션에 SQLAlchemy를 초기화해야 합니다.

SQLAlchemy 객체를 생성한 후 Flask 앱과 연결하는 방식으로 진행합니다.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///board.db'


# MySQL 연결 예시 (사용 시 주석 해제)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://사용자이름:비밀번호@호스트주소:포트/데이터베이스이름'
# 예시: app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost:3306/board_db'

# MariaDB 연결 예시 (사용 시 주석 해제)
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://사용자이름:비밀번호@호스트주소:포트/데이터베이스이름'
# 예시: app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:password@localhost:3306/board_db'


app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

MySQL이나 MariaDB를 Flask + SQLAlchemy로 연결할 때는 pymysql 또는 mysqlclient 같은 DB 드라이버필수입니다.

SQLAlchemy는 ORM이지만, 실제 DB와 통신은 Python용 DB 드라이버가 처리합니다. 즉,

  • SQLAlchemy는 DB 쿼리를 객체화하고,
  • pymysql 같은 드라이버가 실제 DB와 연결해주는 역할을 합니다.

✅ MySQL / MariaDB에서 가능한 드라이버

드라이버 URI 접두어 설치 방법 특징
pymysql mysql+pymysql:// pip install pymysql Pure Python, 호환성 높음
mysqlclient mysql+mysqldb:// pip install mysqlclient C기반, 속도 빠름
asyncmy mysql+asyncmy:// pip install asyncmy 비동기 FastAPI 등에서 활용

 

이렇게 하면 이후에 정의할 모델 클래스들이 자동으로 앱과 연결되어 DB와 상호작용하게 됩니다.

이제 준비가 끝났어요!

다음 단계에서는 실제로 게시글(Post) 모델을 정의하고 테이블과 매핑하는 과정을 배워볼게요.

 

 

3. 데이터 모델 정의와 테이블 매핑 📄

이제 본격적으로 ORM의 핵심 기능인 데이터 모델 정의에 들어갑니다.

여기서는 게시판의 핵심 데이터인 게시글을 관리하는 Post 모델을 만들고, 이 모델이 데이터베이스의 테이블과 어떻게 연결되는지를 알아볼 거예요.

📌 모델 클래스 만들기

SQLAlchemy에서는 DB 테이블을 Python 클래스 형태로 정의합니다.

모델 클래스는 db.Model을 상속하며, 클래스 변수로 각 필드를 정의합니다.

예를 들어 게시글(Post) 모델은 다음과 같이 만들 수 있어요:

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime

db = SQLAlchemy()

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)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
  • id: 기본 키(PK), 자동 증가 정수
  • title: 게시글 제목, 최대 100자, 필수 입력
  • content: 본문 내용, 긴 텍스트 가능, 필수 입력
  • created_at: 글 생성 시간, 자동으로 현재 시간 저장

🧩 선택: 사용자 모델과 관계 설정

시간 관계상 본 과정에서는 인증 기능을 구현하지 않지만, 관계형 DB에서는 모델 간 연결도 아주 중요합니다.

예를 들어 User와 Post 모델을 연결하면 다음과 같은 식으로 구성할 수 있어요.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)

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)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    user = db.relationship('User', backref='posts')

ForeignKeyrelationship을 통해 일대다 관계를 명시할 수 있고,

이를 통해 ORM에서 연관 데이터를 자연스럽게 다룰 수 있어요.

 

이제 모델도 정의했으니, 다음 단계에서는 데이터베이스에 테이블을 실제로 생성하고 마이그레이션 도구를 통해 구조를 관리하는 방법을 배워볼게요.

 

 

4. 모델 간의 관계 설정하기 🔗

ORM의 진짜 강점은 복잡한 테이블 간 관계를 객체 지향적으로 관리할 수 있다는 점이에요.

특히 게시판처럼 게시글과 사용자, 댓글 등이 연결된 구조에서는 ForeignKeyrelationship 기능이 아주 유용합니다.

🔐 관계형 데이터베이스의 기본

관계형 데이터베이스에서는 여러 테이블 간에 관계를 설정해 데이터 중복을 줄이고, 데이터 무결성을 유지할 수 있습니다.

대표적인 관계는 다음과 같아요.

관계 유형 예시
일대일 (One-to-One) User ↔ Profile
일대다 (One-to-Many) User → Post
다대다 (Many-to-Many) Post ↔ Tag

👥 User ↔ Post 관계 구현 예제

이번 예시에서는 한 명의 유저(User)가 여러 개의 게시글(Post)을 작성할 수 있는 일대다(1:N) 관계를 설정해봅니다.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

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)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    user = db.relationship('User', backref='posts')
  • user_id: 외래 키(ForeignKey)로 User 테이블의 id와 연결
  • relationship: Post 인스턴스에서 user 접근, User 인스턴스에서 posts 접근 가능

이제 한 유저가 작성한 모든 게시글을 user.posts로 가져올 수 있고, 게시글에서 작성자를 post.user로 확인할 수 있어요. 정말 직관적이지 않나요?

 

다음 단계에서는 이렇게 정의한 모델을 기반으로 실제 DB에 테이블을 생성하고 Flask-Migrate로 스키마 변경을 관리하는 방법을 알아보겠습니다.

 

 

5. 마이그레이션 도구로 테이블 관리하기 🔄

ORM을 사용해서 모델을 정의했으면, 그걸 기반으로 실제 데이터베이스 테이블을 만드는 작업이 필요합니다.

Flask에서는 db.create_all()을 통해 간단하게 테이블을 생성할 수 있어요.

하지만 실전 개발에서는 마이그레이션 도구를 사용하는 게 더 안전하고 유연합니다.

🛠 db.create_all()으로 초기 테이블 만들기

db.create_all()은 개발 초기 한 번만 사용하는 테이블 생성 함수입니다.

모델 정의가 끝난 후 다음 코드를 실행하면 해당 테이블이 SQLite에 생성됩니다.

from your_app_name import db

db.create_all()

하지만 테이블 구조가 바뀔 때마다 다시 DB를 지우고 만들 순 없잖아요? 그래서 Flask-Migrate를 사용하는 겁니다.

🧬 Flask-Migrate로 안전하게 관리하기

Flask-Migrate는 SQLAlchemy 기반 모델의 변경 사항을 추적하고,

DDL(SQL 명령어) 형태로 자동 변환해서 DB에 적용해주는 도구입니다.

Alembic이라는 강력한 마이그레이션 툴 위에 구축되어 있어요.

설치 및 설정

pip install flask-migrate
from flask_migrate import Migrate

migrate = Migrate(app, db)

이제 커맨드라인 명령을 통해 마이그레이션을 생성하고 적용할 수 있어요.

마이그레이션 명령어 모음

명령어 설명
flask db init 마이그레이션 폴더 초기화
flask db migrate -m "Initial migration" 모델 변경사항을 감지해 마이그레이션 파일 생성
flask db upgrade 실제 DB에 변경사항 반영

upgrade 명령이 완료되면 DB에 posts, users 등 테이블이 생성되어 있을 거예요.

직접 DB 파일을 열어보면 더욱 실감 나겠죠?

 

이제 테이블도 준비 완료!

다음은 이 모델과 테이블을 실제로 다뤄보는 실습 시간입니다.

데이터를 생성하고 저장하고, 다시 불러오는 전 과정을 직접 해볼 거예요.

 

 

6. 실습: 데이터 생성, 저장, 조회 🧪

드디어 지금까지 준비한 모델과 테이블을 바탕으로 실제 데이터를 생성하고 조회해볼 시간입니다.

이번 실습에서는 Flask Shell을 활용해 ORM의 기본 동작을 직접 체험해 볼 거예요.

📥 Flask Shell 실행하기

터미널에서 아래 명령어를 입력하면 Flask 앱의 컨텍스트에서 ORM 객체를 바로 사용할 수 있습니다.

flask shell

그 다음 아래처럼 게시글 데이터를 만들어보고 저장해볼 수 있어요.

>>> from app import db
>>> from models import Post
>>> post = Post(title="첫 번째 글", content="ORM으로 저장된 글입니다!")
>>> db.session.add(post)
>>> db.session.commit()

위 코드로 데이터베이스에 게시글 하나가 저장됩니다.

별도의 SQL 없이도 Python 객체를 통해 저장할 수 있는 게 ORM의 묘미죠!

🔍 저장된 게시글 조회하기

조회는 더 간단해요.

query 속성을 사용하면 모든 데이터를 불러오거나, 조건을 걸어 하나만 찾을 수도 있죠.

>>> Post.query.all()
>>> Post.query.filter_by(title="첫 번째 글").first()
  • all(): 전체 데이터 리스트 조회
  • filter_by(): 조건 검색 (WHERE 절)

📤 데이터를 삭제하거나 수정하려면?

삭제와 수정도 역시 객체 기반으로 처리할 수 있습니다.

SQL 없이도 데이터를 조작할 수 있으니 정말 직관적이에요.

>>> post = Post.query.get(1)
>>> post.title = "제목 수정됨"
>>> db.session.commit()

>>> db.session.delete(post)
>>> db.session.commit()

정말 쉽죠?

SQL이 필요 없는 이 간편함, ORM을 배우는 가장 큰 이유라고 해도 과언이 아닙니다.

 

이제 Flask와 ORM, 그리고 SQLite를 활용해서 기본적인 CRUD(생성, 조회, 수정, 삭제) 작업을 모두 수행할 수 있게 되었어요!

이걸 바탕으로 다음 시간에는 뷰 함수와 연결된 게시판 기능을 구현하게 될 거예요.

 

 

마무리 🎯

지금까지 Flask 애플리케이션에서 ORM을 사용해 데이터베이스와 연동하는 과정을 처음부터 끝까지 살펴봤습니다.

ORM의 개념 이해부터 SQLAlchemy 설치, 모델 정의, 관계 설정, 마이그레이션, 그리고 실전 테스트까지...

꽤 많은 걸 함께 해봤네요.

 

SQL을 몰라도 객체 지향적으로 DB를 다룰 수 있다는 점, 그리고 마치 파이썬 코드만으로 모든 데이터를 조작할 수 있다는 게 ORM의 가장 큰 장점이에요.

 

이제 여러분은 Flask에서 SQLite를 활용해 동적인 데이터를 저장하고, 불러오고, 수정하고, 삭제할 수 있는 기반을 갖췄어요.

다음 단계에서는 이 데이터들을 기반으로 사용자에게 보여주는 인터페이스,

뷰 함수와 템플릿을 통해 웹페이지에서 게시글 목록과 내용을 직접 확인하고 조작하는 방법을 배울 거예요.

 

여기까지 오신 여러분, 정말 고생 많으셨어요.

직접 코드를 실행하고 테스트해보면서 익히면 훨씬 더 오래 기억에 남을 거예요. 그럼 다음 단계에서 다시 만나요!

반응형
반응형

Flask 애플리케이션 구조화 (Blueprint)와 에러 핸들링

복잡해지는 Flask 프로젝트,
하나의 파일로 관리하고 계신가요?
지금이 구조화를 배워야 할 때입니다!

 

 

안녕하세요, Flask 웹 개발 여정을 함께하고 있는 여러분 반갑습니다 😊

셋째 날에는 프로젝트 규모가 커질수록 꼭 필요한 애플리케이션 구조화에러 핸들링에 대해 배워볼 거예요.

처음엔 단순했던 app.py 하나로 잘 운영되던 앱도 기능이 늘어나면 유지보수가 어려워지기 마련이죠.

이럴 때 Blueprint를 활용하면 각 기능을 깔끔하게 나눌 수 있고,

@errorhandlerabort() 등을 통해 사용자에게 더 친절한 오류 메시지를 보여줄 수 있습니다.

실습과 함께 프로젝트 구조를 정리해보면서 한층 더 실전 같은 웹 앱으로 성장시켜볼까요?

 

1. Blueprint 개념과 필요성 🧩

Flask로 웹 애플리케이션을 만들다 보면 처음에는 모든 라우터와 로직을 하나의 app.py 파일에 작성하게 되죠.

하지만 기능이 늘어나고 규모가 커질수록 이 파일은 점점 복잡해지고, 유지보수가 어려워지기 시작합니다.

바로 이럴 때 Blueprint가 등장합니다.

Blueprint란 무엇인가요?

Blueprint는 Flask에서 제공하는 모듈화 도구로, 애플리케이션의 기능을 분리된 파일과 폴더로 나누어 관리할 수 있게 해줍니다.

각각의 Blueprint는 독립적인 라우팅, 템플릿, 정적 파일 등을 가질 수 있어 하나의 작은 앱처럼 동작할 수 있죠.

그리고 최종적으로 메인 애플리케이션에 등록하여 전체 시스템의 일부분으로 동작하게 됩니다.

  • 라우트 및 뷰 함수 분리로 코드 가독성 향상
  • 협업 시 역할 분담 용이 (예: board, auth, admin 모듈)
  • URL prefix로 기능별 주소 체계 구성

Blueprint 적용 전과 후의 구조 비교

구분 적용 전 적용 후
파일 구조 app.py 하나에 모든 코드 작성 board.py, auth.py 등 기능별 파일 분리
라우팅 모든 라우트가 app 객체에 직접 연결됨 Blueprint 내에서 정의 후 app에 등록
템플릿 관리 templates 폴더에 모든 템플릿 혼합 기능별 templates/폴더 구성 가능

Blueprint를 꼭 써야 할까?

처음부터 복잡하게 구조화하려는 강박은 없었으면 해요.

하지만 기능이 3개 이상이라면, 혹은 협업이 필요하거나 앱이 커질 계획이 있다면, Blueprint는 필수입니다.

그리고 이건 단순한 폴더 분할이 아닌 Flask 철학에 맞는 확장 가능한 설계이기도 해요.

자, 이제 기본 개념을 이해했으니...

 

다음은 실습을 통해 실제로 Blueprint를 생성하고 등록해보는 시간을 가져볼게요! 👇

 

 

2. Blueprint 생성 및 등록 실습 🛠️

Blueprint의 이론을 이해했다면 이제 직접 만들어볼 차례죠!

이 실습에서는 게시판 기능을 별도의 board.py 파일로 분리하고, 메인 앱에서는 이를 불러와서 등록하는 흐름을 구성해보겠습니다.

Blueprint 생성: board.py 파일 작성

우선 게시판 관련 기능을 담을 board.py 파일을 생성합니다.

이 안에는 Blueprint 객체를 만들고, 그 안에 라우트를 정의합니다.

from flask import Blueprint, render_template

board_bp = Blueprint('board', __name__, url_prefix='/board')

@board_bp.route('/')
def board_list():
    return render_template('board/list.html')

@board_bp.route('/')
def board_detail(post_id):
    return render_template('board/detail.html', post_id=post_id)
  • Blueprint() 생성 시 url_prefix로 라우트 기본 경로를 지정합니다.
  • 라우트 정의는 @board_bp.route 데코레이터를 사용합니다.

Blueprint 등록: app.py 수정

다음으로 board.py에 정의된 Blueprint를 메인 애플리케이션에 등록해보죠.

app.py를 다음과 같이 수정합니다:

from flask import Flask
from board import board_bp

app = Flask(__name__)
app.register_blueprint(board_bp)

@app.route('/')
def index():
    return '메인 페이지'

이제 /board로 시작하는 URL들은 모두 board.py에서 정의된 라우트로 연결됩니다.

템플릿 디렉토리 분리 및 테스트

템플릿 파일은 templates/board/ 폴더를 만들어 관리합니다.

예를 들어 게시글 목록을 보여주는 템플릿은 아래처럼 구성할 수 있겠죠.

<!-- templates/board/list.html -->
<h1>게시판 목록</h1>
<p>이곳은 게시판 메인입니다.</p>

이제 서버를 실행한 후 http://localhost:5000/board로 접속하면 게시판 라우트가 정상 작동하는지 확인해보세요!

✅ 실습 요약

  • Blueprint는 from flask import Blueprint로 생성
  • 라우트는 @board_bp.route로 작성
  • 메인 앱에 register_blueprint()로 등록

 

다음 장에서는 이 구조를 바탕으로 실제 프로젝트를 리팩터링해보고,

더 정돈된 구조로 발전시켜 보겠습니다! 💪

 

 

3. 기존 프로젝트 구조 리팩터링 🗂️

지금까지는 간단한 예제 중심으로 Blueprint를 실습했죠.

이번에는 실제로 우리가 만든 Flask 애플리케이션을 기능별로 나누고, 디렉토리 구조를 재편해보는 시간을 가져보겠습니다.

프로젝트가 커지면 구조화가 얼마나 중요한지 직접 느껴보실 수 있을 거예요.

디렉토리 구조 개편 예시

myflaskapp/
│
├── app.py                  # Flask 앱 생성 및 Blueprint 등록
├── board/
│   ├── __init__.py         # Blueprint 객체 생성
│   ├── views.py            # 게시판 라우팅 로직
│   └── templates/
│       └── board/
│           ├── list.html   # 게시글 목록 템플릿
│           └── detail.html # 게시글 상세 템플릿
├── static/
│   └── css/
│       └── style.css       # 공통 스타일 시트
└── templates/
    └── base.html           # 공통 레이아웃 템플릿

이처럼 각 기능은 독립된 폴더(board/)로 나뉘고, __init__.py에서 Blueprint를 초기화한 뒤, views.py로 라우트를 따로 관리합니다.

템플릿도 해당 Blueprint 하위에 위치시켜 명확한 소속을 표현하죠.

🔧 예제 코드: board/__init__.py

from flask import Blueprint

board_bp = Blueprint('board', __name__, url_prefix='/board')

from . import views

🧩 예제 코드: board/views.py

from flask import render_template
from . import board_bp

@board_bp.route('/')
def list_posts():
    return render_template('board/list.html')

@board_bp.route('/<int:post_id>')
def post_detail(post_id):
    return render_template('board/detail.html', post_id=post_id)

템플릿 디렉토리 또한 templates/board/에 위치시키면 Flask가 자동으로 해당 위치를 찾아 렌더링합니다.

특히 팀 프로젝트에서 이런 구조는 유지보수성과 협업 효율을 대폭 향상시켜줍니다.

💡 리팩터링 실습 팁

  • URL은 /board, /board/1 등이 예상 경로입니다.
  • 라우트 이름은 가급적 의미 있는 이름으로! list_posts(), post_detail()처럼요.
  • 앱 실행 전 __init__.pyfrom . import views 빠뜨리지 않도록 주의!

여기까지 리팩터링을 잘 마쳤다면 이제 프로젝트 구조가 훨씬 명확하고 확장 가능한 상태가 되었을 거예요.

다음은 이 구조 위에 에러 핸들링을 추가해서 사용자 경험을 한 단계 더 끌어올려보겠습니다!

 

 

4. Flask 에러 핸들링 기법 ⚠️

웹 서비스를 운영하다 보면 오류 상황은 피할 수 없어요.

하지만 오류를 어떻게 처리하느냐에 따라 사용자 경험이 완전히 달라질 수 있습니다.

Flask는 @errorhandler 데코레이터와 abort() 함수를 통해 예외 상황을 보다 우아하게 처리할 수 있도록 도와줍니다.

기본 에러 핸들링: @app.errorhandler

다음은 대표적인 에러인 404 Not Found 오류를 처리하는 코드예요.

@app.errorhandler(404)
def page_not_found(error):
    return render_template('errors/404.html'), 404
  • 404 외에도 403, 500 등의 에러 코드도 커스텀 핸들링 가능해요.
  • HTML 템플릿 파일은 templates/errors/에 분리 저장하는 걸 추천합니다.

abort() 함수로 명시적 에러 발생

Flask에서는 조건에 따라 특정 HTTP 에러를 명시적으로 발생시킬 수도 있어요.

예를 들어 잘못된 게시글 ID가 들어오면 이렇게 처리할 수 있습니다.

from flask import abort

@board_bp.route('/<int:post_id>')
def post_detail(post_id):
    post = get_post_or_none(post_id)
    if post is None:
        abort(404)
    return render_template('board/detail.html', post=post)

이렇게 abort()를 호출하면 Flask가 자동으로 해당 에러 코드에 맞는 핸들러를 호출해줍니다.

Blueprint별 에러 처리도 가능!

재미있는 건, 각 Blueprint에 독립적인 에러 핸들러를 정의할 수 있다는 거예요.

@board_bp.errorhandler(404)
def board_404(error):
    return render_template('board/404.html'), 404

이렇게 하면 게시판 페이지에서 발생한 404는 전용 템플릿으로 분기되고, 나머지 앱 전체에 대해선 @app.errorhandler가 적용되죠.

유저 입장에선 더 세심한 UI로 느껴질 수 있어요.

에러 로깅은 어떻게 하나요?

개발 모드에서는 Flask가 자동으로 오류 스택 트레이스를 보여주죠.

하지만 운영 환경에서는 app.logger를 사용해서 중요한 오류를 로그 파일에 기록하는 것이 좋습니다.

import logging

@app.errorhandler(500)
def internal_error(error):
    app.logger.error(f'Server Error: {error}')
    return render_template('errors/500.html'), 500

이 방식은 운영 서버에서 발생하는 심각한 오류를 추적하고 개선하는 데 매우 유용해요.

✅ 핵심 요약

  • @app.errorhandler 또는 @blueprint.errorhandler로 커스텀 오류 처리
  • abort()로 조건부 오류 강제 발생 가능
  • app.logger를 통해 서버 오류 기록

 

다음은 요청 전후의 공통 작업을 자동화하는 방법인 요청 훅과 미들웨어 유사 기능에 대해 알아보겠습니다.

서버가 모든 요청을 어떻게 처리하는지 흐름을 이해하면, 더 강력한 기능도 구현할 수 있어요!

 

 

5. 요청 훅과 미들웨어 유사 기능 🔄

Flask에는 Django처럼 미들웨어 체인이 명시적으로 존재하지는 않지만, 그 대신 요청 훅(hook)을 이용해 유사한 기능을 구현할 수 있어요.

전역적으로 실행되는 전처리/후처리 로직을 통해 인증 검사, 로깅, CORS 헤더 추가 등 다양한 동작을 자동화할 수 있습니다.

@app.before_request / @app.after_request

모든 요청에 대해 실행되는 전처리와 후처리 훅은 다음처럼 정의할 수 있어요:

from flask import request

@app.before_request
def log_request_info():
    print(f"[요청] {request.method} {request.path}")

@app.after_request
def add_header(response):
    response.headers['X-Frame-Options'] = 'DENY'
    return response
  • before_request: DB 연결, 사용자 인증 등 선처리에 유용
  • after_request: 응답 헤더 추가, 캐시 처리 등에 사용

Blueprint에서 요청 훅 쓰기

요청 훅은 app뿐 아니라 Blueprint에서도 사용할 수 있어요.

예를 들어 게시판 라우트에만 접근 권한을 체크하고 싶을 땐 아래처럼 작성합니다.

@board_bp.before_request
def check_board_auth():
    if not user_has_board_permission():
        return "접근이 제한된 페이지입니다.", 403

이렇게 하면 /board로 시작하는 URL에 대해서만 인증 로직이 동작해요.

전체 앱과 독립적으로 작동하니 구조 관리에 매우 유리하죠.

WSGI 미들웨어 소개 (간략)

보다 정교한 미들웨어 처리가 필요하다면 Flask의 하위 레벨인 WSGI 미들웨어를 사용할 수도 있어요.

다만 이는 Flask 자체보다는 웹 서버와의 연동 관점에서 다뤄지며, 대부분의 경우 요청 훅으로 충분합니다.

✅ 요약 정리

  • before_request는 인증, 로깅 등 요청 전 공통 처리에 적합
  • after_request는 응답 헤더 수정, 후처리에 사용
  • Blueprint마다 훅 설정 가능 → 인증, 필터 등 기능별 적용

이제 Flask 앱이 점점 더 체계적인 구조와 기능을 갖추게 되었어요.

마지막으로, 이런 기능들을 더욱 풍부하게 만들어주는 Flask 확장들을 소개하면서 이번 단원을 마무리해볼게요.

 

 

6. Flask 확장 라이브러리 소개 📦

Flask는 마이크로 프레임워크인 만큼, 기본 기능이 최소화되어 있어요.

대신에 필요한 기능을 선택적으로 확장할 수 있는 수많은 라이브러리가 존재합니다.

이번에는 Flask 개발에서 자주 사용되는 확장 도구들을 간단히 정리해볼게요.

1. Flask-SQLAlchemy - ORM 기능 🧮

SQLAlchemy는 강력한 ORM(Object-Relational Mapping) 라이브러리입니다.

Flask-SQLAlchemy는 이를 Flask에 쉽게 통합할 수 있도록 도와주는 확장이죠.

  • ORM을 통해 SQL 없이도 DB 조작 가능
  • 다양한 DB 지원 (MySQL, PostgreSQL, SQLite 등)

2. Flask-Migrate - DB 마이그레이션 도구 🔄

Flask-Migrate는 데이터베이스 스키마 변경을 관리하는 도구예요.

프로젝트 중반에 테이블 구조가 바뀔 때도 명령어 한 줄로 변경 사항을 적용할 수 있어 매우 유용합니다.

flask db init
flask db migrate -m "Add users table"
flask db upgrade

3. Flask-WTF - 폼 처리 및 검증 📄✅

웹 폼은 사용자 입력의 핵심이죠.

Flask-WTF는 Flask에서 폼 클래스 기반 입력 처리를 가능하게 해주는 확장입니다.

CSRF 보호와 유효성 검사도 기본으로 제공해요.

  • HTML 폼 → Python 클래스 기반 처리
  • 입력 검증 및 에러 메시지 처리 자동화

4. Flask-Login - 사용자 인증 🔐

회원 가입, 로그인, 로그아웃 기능을 구현하려면 Flask-Login이 제격입니다.

인증 흐름을 매우 간단하게 만들어주는 유용한 도구죠.

from flask_login import LoginManager

login_manager = LoginManager()
login_manager.init_app(app)

 

✅ 이 외에도 인기 있는 Flask 확장

  • Flask-Caching – 캐시 처리로 성능 향상
  • Flask-Mail – 이메일 전송 기능
  • Flask-RESTful – REST API 개발을 위한 구조화 도구

 

우리가 앞으로 이 커리큘럼에서 활용할 주요 확장은 Flask-SQLAlchemy, Flask-Migrate, Flask-WTF예요. 인증이 필요한 기능에서는 Flask-Login도 함께 써볼 거고요.

필요에 따라 다른 확장도 자유롭게 추가할 수 있어요.

이제 Flask의 구조화와 오류 처리, 요청 훅, 확장까지 모두 익혔다면, 복잡한 웹 애플리케이션도 자신감 있게 개발할 수 있어요!

다음 수업에서는 ORM과 데이터베이스를 본격적으로 다뤄볼 예정이니 기대해주세요 😊

 

지금까지 Flask 애플리케이션을 구조화하는 방법부터 에러를 다루는 방법, 공통 동작을 처리하는 요청 훅, 그리고 개발을 도와주는 확장 도구까지 차근차근 살펴봤습니다.

처음엔 조금 복잡해 보일 수 있지만, 실제로 코드를 나누고 정리하다 보면 더 깔끔하고 안정적인 서비스 구조를 만들 수 있어요.

특히 Blueprint를 활용한 모듈화는 프로젝트가 커졌을 때 그 진가를 발휘합니다.

더불어, @app.errorhandler, abort(), before_request 같은 기능은 개발자의 세심함을 사용자에게 전달할 수 있는 강력한 도구죠.

앞으로 더 복잡한 기능을 구현하기 위해선 이런 기초를 튼튼히 다지는 게 중요하답니다 💪

 

다음 강의에서는 ORM을 활용한 데이터베이스 연동을 본격적으로 다루게 될 텐데요,

오늘 배운 구조화 개념이 이후 내용과도 깊게 연결되니 꼭 복습해두세요.

직접 실습을 통해 익히는 것이 최고의 학습 방법이라는 것, 잊지 마세요!

반응형
반응형

파이썬 Flask 라우팅, 요청/응답 처리와 템플릿 렌더링

웹 개발,
단순히 URL에 반응하는 것만으로는 부족하죠.
동적으로 데이터를 받고, 응답을 처리하고,
아름다운 화면까지 보여줘야 진짜 웹 애플리케이션입니다!

 

 

안녕하세요 여러분!

Flask의 기초를 잡은 첫날에 이어, 오늘은 Flask 라우팅의 심화HTTP 요청 및 응답 처리, 그리고 템플릿 렌더링까지 실전 웹 개발에 필요한 핵심 기능들을 배우는 시간을 가져보려고 해요.

특히 Jinja2 템플릿을 활용한 동적 페이지 구현은 처음 보면 살짝 낯설 수 있지만, 익숙해지면 정말 강력한 도구가 된답니다.

또한 클라이언트로부터 전달받는 다양한 형태의 요청 데이터를 처리하는 방법,

그리고 응답의 생성과 상태 관리까지 다뤄볼 예정이에요.

오늘 내용을 잘 익히면, 여러분만의 멋진 웹 인터페이스를 만들 수 있는 기본기를 탄탄히 다질 수 있을 거예요 😊

 

1. Flask 라우팅 심화 🌐

1-1. 동적 경로와 변수

Flask의 가장 강력한 기능 중 하나는 라우트에서 동적 경로를 쉽게 처리할 수 있다는 점이에요.

예를 들어 블로그 글을 클릭했을 때 /posts/3처럼 글 번호를 URL에 포함시키고 싶을 때가 있죠?

그럴 때는 이렇게 작성해요:

@app.route('/posts/<int:post_id>')
def show_post(post_id):
    return f"Post ID: {post_id}"

 

여기서 <int:post_id>는 URL의 일부분을 정수형 변수로 받아와서 파이썬 함수의 인자로 넘기는 역할을 해요.

string, float, path 같은 변환기도 사용할 수 있답니다.

1-2. HTTP 메서드 라우팅

기본적으로 Flask의 라우트는 GET 요청만 처리해요.

그런데 데이터 저장이나 수정이 필요할 때는 POST, PUT, DELETE 같은 메서드를 써야 하겠죠?

@app.route('/submit', methods=['GET', 'POST'])
def submit():
    if request.method == 'POST':
        return 'Form submitted!'
    return 'Submit your form.'

 

이렇게 methods 인자를 사용하면 GET과 POST를 모두 처리할 수 있어요.

사용자 입력을 받는 폼이나 API를 만들 때 필수적인 기능이에요!

1-3. 라우팅 우선순위와 404 처리

라우트가 여러 개 있을 경우, Flask는 위에서 아래로 읽으면서 먼저 일치하는 것을 실행해요.

그래서 더 구체적인 라우트를 먼저 정의하는 것이 좋아요.

또한 정의되지 않은 경로로 사용자가 접속하면 Flask는 기본적으로 404 Not Found 에러 페이지를 보여줘요.

이 페이지도 @app.errorhandler(404) 데코레이터로 커스터마이징할 수 있어요.

@app.errorhandler(404)
def not_found(e):
    return render_template('404.html'), 404

 

사용자 경험을 위한 작은 배려! 에러 페이지도 예쁘게 만들어두면 좋겠죠?

  • 동적 경로는 <타입:변수명> 형식으로 지정
  • methods로 다양한 HTTP 요청 대응
  • 라우트 순서가 중요! 더 구체적인 경로 먼저 정의

 

 

2. HTTP 요청과 응답 처리 📩

2-1. Request 객체 이해하기

Flask에서는 request 객체를 통해 클라이언트로부터 받은 다양한 데이터를 조회할 수 있어요.

이 객체는 flask 모듈에서 자동으로 제공되며, 전역에서 접근 가능합니다.

다음은 주요 속성들입니다:

속성 설명
request.args URL 쿼리스트링 (GET 방식)의 파라미터를 딕셔너리 형태로 반환
request.form 폼 데이터를 조회할 때 사용 (POST 방식)
request.get_json() JSON 형식의 본문 데이터를 파싱하여 반환 (API 제작 시 유용)

예시 코드

from flask import request

@app.route('/search')
def search():
    keyword = request.args.get('q')
    return f"검색어: {keyword}"

2-2. 응답 생성 및 상태코드

Flask에서는 반환값으로 문자열을 주면 자동으로 HTTP 응답이 만들어지지만,

Response 객체를 직접 생성하거나 jsonify를 활용해 JSON 형식으로 응답을 보낼 수도 있어요.

from flask import Response, jsonify

@app.route('/custom')
def custom_response():
    return Response("직접 만든 응답", status=201)

@app.route('/api/data')
def api_data():
    data = {"name": "Flask", "version": 2.0}
    return jsonify(data), 200

 

상태 코드 200(성공), 201(생성됨), 400(잘못된 요청), 404(페이지 없음), 500(서버 에러) 등은 직접 지정할 수 있어요.

2-3. 쿠키와 세션

사용자 상태를 유지하려면 쿠키세션을 사용해야 해요.

Flask에서는 request.cookies로 쿠키를 읽고, response.set_cookie로 저장할 수 있어요.

세션은 session 객체를 사용해 딕셔너리처럼 데이터를 저장할 수 있어요.

이를 통해 로그인 상태를 유지하거나, 특정 사용자에게 맞춤 정보를 제공할 수 있죠.

from flask import session

@app.route('/set_session')
def set_session():
    session['username'] = 'python_user'
    return '세션 저장 완료!'

@app.route('/get_session')
def get_session():
    return f"저장된 사용자: {session.get('username')}"

 

세션은 내부적으로 쿠키를 사용하긴 하지만, 암호화되어 안전하고 편리하게 데이터를 저장할 수 있어요.

단, 세션을 사용하려면 app.secret_key를 설정해줘야 한답니다.

 

 

3. 템플릿 렌더링과 Jinja2 🧩

3-1. Jinja2 기본 문법

Flask는 Jinja2라는 템플릿 엔진을 기본으로 사용합니다.

Python 코드를 HTML 안에 자연스럽게 녹여서 동적인 웹페이지를 만들 수 있게 해주죠!

 

기본 문법은 아래와 같아요:

  • {{ 변수 }} : 파이썬 변수 출력
  • {% if 조건 %}, {% for 요소 in 리스트 %} : 제어문

예시 코드 (템플릿)

<ul>
  {% for user in users %}
    <li>{{ user }}</li>
  {% endfor %}
</ul>

3-2. render_template 사용법

템플릿 파일은 Flask 프로젝트의 templates 폴더 안에 두어야 하고, 이를 불러오려면 render_template 함수를 사용합니다.

from flask import render_template

@app.route('/hello')
def hello():
    return render_template('hello.html', name='Flask')

 

이렇게 하면 templates/hello.html을 찾아서 {{ name }} 부분에 'Flask'를 출력하게 돼요.

 

 

3-3. 템플릿 상속과 레이아웃 구성

Jinja2는 템플릿 상속을 지원해서, 공통된 레이아웃을 base.html에 작성하고 다른 템플릿에서 상속받을 수 있어요.

예를 들어:


<body>
  <header><h1>My Site</h1></header>
  {% block content %}{% endblock %}
</body>


{% extends "base.html" %}
{% block content %}
  <p>Hello, {{ name }}!</p>
{% endblock %}

 

이 구조 덕분에 중복을 줄이고, 각 페이지에 필요한 콘텐츠만 작성하면 되니까 유지보수도 훨씬 쉬워지죠!

3-4. 템플릿에서 동적 콘텐츠 출력

템플릿은 단순히 정적인 HTML을 보여주는 게 아니라,

Python 쪽에서 넘긴 데이터를 받아서 동적으로 리스트를 출력하거나 조건 분기를 적용할 수도 있어요.

@app.route('/posts')
def post_list():
    posts = ['첫 번째 글', '두 번째 글', '세 번째 글']
    return render_template('posts.html', posts=posts)

 

템플릿(posts.html)에서는 아래처럼 반복문을 사용해서 출력할 수 있죠:

<ul>
  {% for post in posts %}
    <li>{{ post }}</li>
  {% endfor %}
</ul>

 

정말 마법 같죠?

Flask와 Jinja2만 있으면 동적 웹 페이지를 어렵지 않게 만들 수 있답니다 ✨

 

 

4. 정적 파일 제공 🎨

4-1. static 디렉토리의 역할

웹페이지가 동작하려면 CSS, 이미지, JavaScript 같은 정적 파일이 꼭 필요하죠.

Flask에서는 static/ 폴더를 통해 이 정적 리소스를 제공해요.

 

예를 들어

static/style.css라는 파일이 있다면,

템플릿에서 아래처럼 불러올 수 있어요:

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

 

url_for('static', filename='파일명')은 Flask에서 정적 파일의 URL을 안전하게 생성해주는 방법이에요.

경로를 직접 쓰는 것보다 이 방식이 훨씬 안전하답니다.

4-2. 정적 파일 구성 예시

프로젝트 내 디렉토리 구성 예시는 아래와 같아요:

project/
│
├── app.py
├── static/
│   ├── style.css
│   └── logo.png
└── templates/
    └── index.html

 

템플릿 안에서 이 파일들을 다음과 같이 불러올 수 있어요:

<img src="{{ url_for('static', filename='logo.png') }}" alt="로고">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

4-3. 간단한 스타일링 실습

style.css를 만들어 아주 간단한 배경색과 폰트를 설정해볼게요.

/* static/style.css */
body {
  background-color: #f9f9f9;
  font-family: 'Noto Sans KR', sans-serif;
}
h1 {
  color: #1b6ca8;
}

 

그리고 템플릿에서 해당 CSS를 로딩하면 웹페이지에 기본 스타일이 적용돼요.

이렇게 하면 프로젝트에 디자인적인 생명이 불어넣어지죠!

TIP 💡

Bootstrap이나 Tailwind 같은 외부 CSS 프레임워크도 정적 파일로 함께 사용하거나 CDN 링크로 불러와서 템플릿에 간단히 적용할 수 있어요!

 

 

5. 라우트 및 템플릿 실습 페이지 만들기 🛠️

5-1. 여러 페이지 연결하기

Flask에서 여러 웹페이지를 만드는 방법은 정말 간단해요!

각 페이지마다 라우트템플릿을 하나씩 연결하면 끝입니다.

예를 들어 메인 페이지와 소개 페이지를 만들어 서로 링크로 연결해보죠.

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/about')
def about():
    return render_template('about.html')

 

템플릿에서는 url_for을 활용해서 내부 링크를 쉽게 만들 수 있어요 👇

<a href="{{ url_for('index') }}">홈으로</a>
<a href="{{ url_for('about') }}">소개 페이지</a>

5-2. 동적 데이터 출력 실습

이번에는 파이썬 리스트를 만들어 템플릿에 넘겨보고,

Jinja2의 반복문을 사용해 동적으로 내용을 출력해볼 거예요.

마치 실제 게시판처럼요!

@app.route('/posts')
def posts():
    post_list = [
        {'title': '첫 번째 글', 'author': '홍길동'},
        {'title': '두 번째 글', 'author': '이몽룡'},
        {'title': '세 번째 글', 'author': '성춘향'}
    ]
    return render_template('posts.html', posts=post_list)

 

posts.html에서는 이렇게 리스트를 테이블로 출력할 수 있어요:

<table border="1">
  <tr><th>제목</th><th>작성자</th></tr>
  {% for post in posts %}
    <tr>
      <td>{{ post.title }}</td>
      <td>{{ post.author }}</td>
    </tr>
  {% endfor %}
</table>

5-3. 실습 마무리 및 팁

이제 여러분은 라우팅을 설정하고, HTML 템플릿을 렌더링하고, 동적 데이터를 출력하는 전 과정을 경험해보셨어요.

이걸 바탕으로 나중에는 사용자 로그인, 댓글 작성, 데이터베이스 연동 같은 고급 기능도 훨씬 수월하게 이해할 수 있어요.

 

항상 시작은 작게, 그러나 제대로! 지금 만든 코드들도 훌륭한 출발점이 될 수 있어요.

  • 여러 라우트로 페이지 구성하기
  • Jinja2 반복문으로 리스트 출력하기
  • 정적 링크와 템플릿 상속으로 구조화하기

 

 

6. 폼 입력과 데이터 처리 실습 ✍️

6-1. HTML 폼 만들기

사용자의 입력을 서버에 전달하려면 이 필요하겠죠.

HTML에서는 <form> 태그를 사용하고, Flask는 이를 POST 방식으로 받아 처리할 수 있어요.

<form action="/contact" method="POST">
  이름: <input type="text" name="name"><br>
  메세지: <textarea name="message"></textarea><br>
  <input type="submit" value="전송">
</form>

6-2. POST 요청 처리하기

Flask에서는 request.form을 사용해서 사용자가 입력한 데이터를 받아올 수 있어요.

그리고 조건문으로 GET인지 POST인지 구분해서 처리하면 돼요!

@app.route('/contact', methods=['GET', 'POST'])
def contact():
    if request.method == 'POST':
        name = request.form['name']
        message = request.form['message']
        return render_template('result.html', name=name, message=message)
    return render_template('contact.html')

 

result.html에서는 이렇게 입력값을 출력할 수 있어요:

<p>{{ name }}님이 보내신 메세지입니다.</p>
<blockquote>{{ message }}</blockquote>

6-3. 폼 처리 요약과 유의점

  • GET 요청은 주로 폼을 보여줄 때 사용
  • POST 요청은 실제 입력 데이터를 서버로 보낼 때 사용
  • request.form을 통해 데이터를 추출하고 응답에 활용

지금은 단순히 입력값을 받아 출력하는 수준이지만,

나중엔 이 데이터를 DB에 저장하거나 이메일로 전송할 수도 있답니다!

실습 결과 요약 📝

기능 설명
폼 렌더링 GET 요청 시 contact.html 렌더링
데이터 수신 POST 요청 시 사용자의 입력값을 추출
결과 출력 result.html에서 입력값을 표시

 

마무리 ✨

이번 시간에는 Flask의 핵심 기능 중 하나인 라우팅요청/응답 처리,

그리고 템플릿 렌더링까지 웹 애플리케이션을 구성하는 기본 요소들을 차근차근 살펴봤어요.

단순히 URL을 연결하는 것에서 그치지 않고, 사용자의 요청을 읽고 응답을 생성하며, 템플릿을 통해 멋진 동적 페이지까지 만들어낸 경험은 정말 인상적이었을 거예요 😊

 

이제 여러분은 단순한 Flask 앱이 아니라, 실제 사용자와 상호작용할 수 있는 인터페이스 중심의 웹 서비스를 만들 수 있는 준비가 되셨습니다.

아직 데이터베이스나 사용자 인증 같은 내용은 남아있지만, 오늘 배운 내용을 기반으로 앞으로의 실습도 훨씬 수월하게 진행될 거예요. 😄

 

반응형
반응형

파이썬 Flask 기본 개념과 개발 환경 설정

웹 개발, 어떻게 시작해야 할까요?
너무 무겁고 복잡한 프레임워크에 지쳤다면,
Flask로 가볍고 유연하게 시작해보세요!

 

 

안녕하세요, 여러분 반갑습니다!

오늘은 웹 개발 입문자에게 딱 맞는 Python 기반 마이크로 프레임워크 Flask에 대해 함께 배워볼 거예요.

Flask는 배우기 쉽고, 필요한 기능만 붙여서 쓸 수 있어서 초보자에게 정말 잘 맞는 프레임워크랍니다.

이 글에서는 Flask가 어떤 도구인지, 왜 사용하는지부터 개발 환경을 설정하고 "Hello, World!"까지 웹앱을 직접 실행해보는 것까지 단계별로 친절하게 설명드릴게요.

천천히 따라오시면서 한 줄 한 줄 실행해 보세요.

분명 재미있고 보람찬 시간이 될 거예요. 😊

 

1. Flask란 무엇인가요? 🧩

웹 개발을 처음 접하는 분들이라면 Flask라는 이름이 조금 생소하게 들릴 수도 있습니다.

하지만 Python 언어를 배우셨다면, Flask는 웹 애플리케이션 세계로 자연스럽게 이어주는 친절한 안내자 같은 존재예요. 😄

Flask는 마이크로 웹 프레임워크입니다.

여기서 '마이크로'란 작고 기능이 제한적이라는 뜻이 아니라, 필수적인 최소한의 구성만 제공한다는 의미입니다.

즉, 필요한 기능을 사용자가 직접 선택하고 조립해서 쓸 수 있어요.

🔍 웹 프레임워크란?

웹 프레임워크는 웹 애플리케이션 개발을 쉽게 해주는 도구 모음이에요.

일반적으로 웹 개발에는 HTTP 처리, 라우팅, 요청/응답 관리, 템플릿 렌더링, 데이터베이스 연동 등 다양한 기능이 필요합니다.

이걸 모두 직접 짜려면 시간도 오래 걸리고, 실수도 많겠죠?

그래서 우리는 웹 프레임워크를 사용합니다.

대표적으로 Django는 많은 기능이 내장된 풀스택 프레임워크이고,

Flask는 꼭 필요한 기능만 기본으로 제공하는 마이크로 프레임워크입니다.

🧠 Flask의 내부 구조와 작동 원리 간단히 알아보기

Flask는 내부적으로 WSGI(Web Server Gateway Interface)라는 표준을 따릅니다.

이 덕분에 Flask 애플리케이션은 다양한 Python 웹 서버와 호환될 수 있어요.

 

간단히 말하면, 사용자의 브라우저 요청 → Flask가 요청 처리 → 결과를 응답으로 반환하는 흐름이에요.

이 요청-응답 흐름을 이해하는 것이 이후 라우팅, 뷰 함수, 템플릿 등 모든 Flask 기능을 배우는 기초가 됩니다.

  • Flask는 단순하고 가볍습니다 — 필요한 기능만 골라서 사용 가능
  • WSGI 표준에 따라 Python 기반 웹 서버와 호환됩니다
  • 라우팅, 요청 처리, 응답 생성 등 웹의 기본 흐름을 직접 경험할 수 있어요

이제 Flask의 기본 개념과 작동 방식이 조금 이해되셨죠? 😊

다음 섹션에서는 Flask가 왜 이렇게 많이 사랑받는지, 어떤 점이 특별한지를 구체적으로 알아볼 거예요!

 

 

2. Flask의 주요 특징과 장점 💡

Flask는 단순하면서도 확장 가능한 구조 덕분에 초보자부터 전문가까지 모두가 애용하는 프레임워크입니다. "필요한 것만 붙인다!"는 유연한 설계 철학이 Flask의 핵심이에요.

그럼 Flask가 왜 사랑받는지, 어떤 강점들이 있는지 하나씩 살펴볼까요?

🎯 Flask의 핵심 특징

  • 심플한 구조: 단 하나의 파일로도 전체 웹 앱을 실행할 수 있어요.
  • 유연성: 프로젝트 구조를 자유롭게 설계 가능! 마이크로서비스에도 적합합니다.
  • 확장성: 플러그인 및 확장 라이브러리를 통해 기능 추가 가능 (예: SQLAlchemy, Flask-Login).
  • 방대한 커뮤니티와 자료: 공식 문서가 잘 되어 있고, 튜토리얼도 엄청 많아요.

💻 Flask vs Django: 비교로 보는 특징

비교 항목 Flask Django
프레임워크 유형 마이크로 프레임워크 풀스택 프레임워크
구조 자유롭고 유연함 엄격한 구조
초보자 적합성 빠르게 시작 가능 처음엔 다소 복잡
확장성 라이브러리 추가 방식 내장 기능 풍부

이처럼 Flask는 자유도와 단순함이 큰 매력입니다.

게다가 파이썬스럽게 직관적인 코드 작성이 가능해서, 배우면 배울수록 더 잘 만들고 싶어지는 프레임워크예요.

이제 Flask의 매력을 알았으니, 다음은 개발 환경을 어떻게 구성할지 알아볼 차례입니다! ✨

 

 

3. 개발 환경 구성하기 (venv, 설치) 🛠

Flask 개발을 시작하기 위해선 먼저 작업을 위한 안전한 공간, 즉 가상환경을 만드는 게 중요합니다.

왜냐하면 프로젝트마다 사용하는 라이브러리 버전이 다를 수 있고, 시스템 전체에 영향을 주지 않기 위해서죠.

🌱 가상환경 만들기

다음은 Python 내장 도구 venv를 사용해 가상환경을 만들고 활성화하는 과정입니다.

# 가상환경 생성
python -m venv venv

# Windows에서 활성화
venv\Scripts\activate

# macOS / Linux에서 활성화
source venv/bin/activate

터미널 프롬프트 앞에 (venv)가 붙으면 성공입니다. 이제 Flask를 설치해볼 차례예요.

📦 Flask 설치하기

pip install Flask

정상 설치되었다면, 다음 명령어로 설치된 버전을 확인할 수 있어요.

python -m flask --version

🗂 프로젝트 기본 구조

지금은 단일 파일 구조로 충분합니다.

이후 앱이 커지면 파일을 나누게 되지만, 현재는 아래처럼 하나의 파일로 시작해도 전혀 문제 없어요.

/프로젝트폴더
│
├── venv/               # 가상환경 폴더
├── app.py              # Flask 메인 애플리케이션

간단하죠?

다음 단계에서는 app.py 내부 구조와 실행 흐름을 차근차근 배워볼 거예요.

Flask가 어떻게 실행되고, URL 요청을 어떻게 처리하는지 눈으로 확인할 시간입니다!

 

 

4. Flask 애플리케이션의 구조 이해하기 🧱

본격적으로 Flask 앱을 실행해보기 전에,

app.py 안에 어떤 코드가 들어가고 어떤 구조로 작동하는지부터 알아야 해요.

이해가 되면 앞으로 라우팅이든 템플릿이든, 어떤 기능을 추가할 때도 훨씬 수월해집니다. 😎

🧪 Flask 애플리케이션 생성: Flask(__name__)

from flask import Flask

app = Flask(__name__)

이 코드가 Flask 애플리케이션의 시작입니다.

여기서 __name__은 파이썬 내장 변수로 현재 모듈의 이름을 나타내며,

Flask는 이를 통해 현재 파일이 직접 실행된 것인지 혹은 다른 모듈에서 import된 것인지를 구분해요.

🔀 라우팅과 뷰 함수 기본 구조

@app.route("/")
def home():
    return "Hello, Flask!"

@app.route()는 Flask에서 URL 경로를 정의하는 방법입니다.

위 예시에서는 / (루트 경로)로 들어오는 요청에 대해 home() 함수가 실행되고,

브라우저에 Hello, Flask!가 출력돼요.

 

즉, 브라우저 요청 → Flask 라우터 → 뷰 함수 → 응답 반환의 구조입니다.

  1. 브라우저에서 http://localhost:5000/ 요청
  2. Flask 내부 라우팅 시스템이 해당 URL을 찾음
  3. home() 함수 실행
  4. 문자열을 HTTP 응답으로 브라우저에 전달

🚦 개발 서버 실행: flask run

# 환경변수 설정 (Windows)
set FLASK_APP=app.py

# macOS / Linux
export FLASK_APP=app.py

# 개발 서버 실행
flask run

이제 브라우저에서 http://localhost:5000에 접속하면 방금 만든 응답 메시지를 볼 수 있어요!

또한 --debug 옵션을 주면 코드 수정 시 자동 반영되고, 에러도 브라우저에서 확인할 수 있답니다.

 

지금까지 우리는 Flask 앱의 기본 구조를 확인했고, 어떻게 라우팅을 통해 요청을 처리하는지 익혔습니다.

이제 정말 재미있는 시간! 첫 번째 Flask 애플리케이션을 만들어볼 차례예요. ✨

 

 

5. 라우팅과 뷰 함수의 개념 🌐

웹 애플리케이션에서 라우팅(Routing)은 사용자가 특정 URL에 접근했을 때 어떤 기능을 실행할지 결정하는 중요한 역할을 해요.

Flask에서는 라우팅과 뷰 함수(View Function)를 아주 간단하게 설정할 수 있습니다.

🧭 라우팅(Routing)이란?

라우팅은 URL 경로와 처리할 함수를 연결하는 과정이에요.

예를 들어

사용자가 /hello라는 주소에 접근했을 때 어떤 메시지를 보여줄지를 Flask에게 알려줘야 하죠.

@app.route('/hello')
def say_hello():
    return "안녕하세요!"

위 코드에서 @app.route('/hello')는 URL 경로 /hello를 처리하는 역할을 해요.

사용자가 이 경로로 접속하면 say_hello() 함수가 실행되고, 그 반환값이 브라우저에 출력됩니다.

👀 뷰 함수(View Function)의 역할

뷰 함수는 URL 요청이 들어왔을 때 실행되는 함수입니다.

이 함수는 반드시 문자열, HTML, JSON 등 응답 가능한 형태의 데이터를 반환해야 해요.

즉, 라우팅은 주소와 함수를 연결하고, 뷰 함수는 실제로 실행되는 동작을 정의합니다.

🔄 클라이언트 요청부터 응답까지의 흐름

  1. 사용자가 브라우저에서 /hello 주소로 요청을 보냄
  2. Flask가 해당 경로에 맞는 라우트를 찾음
  3. say_hello() 뷰 함수가 실행됨
  4. 반환된 응답을 HTTP 형식으로 변환해 브라우저에 전달

🌐 다양한 라우트 경로 구성 팁

  • @app.route('/user/<username>') : 동적인 URL 처리 (예: /user/alice)
  • @app.route('/post/<int:post_id>') : 숫자형 ID 처리 (예: /post/42)

Flask의 라우팅 시스템은 정말 강력하고 직관적이에요.

필요하다면 methods=['GET', 'POST'] 옵션으로 요청 방식을 제한할 수도 있답니다.

 

다음 단계에서는 이 라우팅 구조를 직접 활용하여, 실습으로 "Hello, World!" 앱을 만들어볼 거예요! 😄

 

 

6. Hello, World! 앱 만들기 🚀

드디어 Flask 웹 애플리케이션을 직접 만들어볼 시간이에요! 지금까지 배운 내용을 바탕으로, 가장 기본적인 "Hello, World!" 메시지를 띄우는 웹 서비스를 구현해볼게요. 😄

👨‍💻 app.py 파일 작성

app.py라는 이름으로 아래 코드를 작성하세요.

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello, World!"

딱 5줄이면 끝!

@app.route("/")는 루트 경로를 의미하고,

hello() 함수는 브라우저에 Hello, World!를 보여주는 역할을 합니다.

🚀 실행해보기

# 환경 변수 설정 (macOS/Linux)
export FLASK_APP=app.py

# Windows
set FLASK_APP=app.py

# 실행
flask run

명령어를 입력하고 나면 아래처럼 개발 서버가 실행됩니다.

 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)

웹 브라우저를 열고 http://localhost:5000에 접속해보세요.

짜잔~! "Hello, World!"라는 문구가 반겨줄 거예요. 🎉

🔁 기타 실행 팁

  • 포트를 바꾸고 싶을 땐 flask run -p 8080 처럼 -p 옵션을 사용해보세요.
  • --debug 옵션을 쓰면 코드 수정이 실시간 반영돼요!
  • 서버 종료는 CTRL + C

이제 여러분은 Flask 애플리케이션을 직접 만들고, 브라우저에서 요청을 처리해보는 과정을 경험하셨어요!

웹 개발의 첫 단추, 잘 꿰셨습니다. 👏

다음 단계부터는 이 구조를 바탕으로 템플릿, 폼, 데이터베이스 등 다양한 기능을 붙여나가게 될 거예요.

 

 

마무리 ✨

여기까지 따라오셨다면, Flask의 기본 개념과 개발 환경 설정부터 애플리케이션 실행까지 한 사이클을 완주하신 거예요. 🎉

단 몇 줄의 코드로 웹 서버를 만들고, 브라우저를 통해 직접 결과를 확인하는 그 짜릿한 경험, 어떠셨나요?

오늘 배운 내용은 앞으로 Flask를 이용한 웹 개발을 위한 아주 탄탄한 기초가 됩니다.

이후 템플릿을 연결하거나, 사용자 입력을 받고, 데이터를 저장하는 등 더 복잡한 기능으로 확장해 나가더라도,

모든 흐름의 뿌리는 이 기본적인 라우팅 → 뷰 함수 → 응답입니다.

 

이제 여러분도 "나, Flask 웹 앱 만들 수 있어!"라고 자신 있게 말할 수 있어요.

다음 글에서는 템플릿 엔진인 Jinja2를 통해 HTML을 다루고, 사용자 입력을 처리하는 방법도 하나씩 배워볼 예정입니다. 기대해주세요!

 

🙌 지금까지 수고 많으셨습니다.

실습을 꼭 따라해 보시고, 직접 오류도 만나보고 해결해 보는 과정이 가장 큰 공부가 됩니다!

반응형

+ Recent posts