Chapter 4-6 실습_블로그 구현 (Flask-MySQL를 활용) posts_routes.py

2025. 4. 22. 14:22·Flask
목차
  1. 프로젝트 구조
  2. 전체 코드 (posts_routes.py)
  3. 1. create_posts_blueprint 함수
  4. Blueprint 설정
  5. 2. GET 및 POST 요청 처리
  6. 게시글 목록 조회 (GET /posts)
  7. 게시글 생성 (POST /posts)
  8. 3. 게시글 상세 조회, 수정, 삭제 (GET /posts/<int:id>, PUT /posts/<int:id>, DELETE /posts/<int:id>)
  9. 게시글 상세 조회 (GET /posts/<id>)
  10. 게시글 수정 (PUT /posts/<id>)
  11. 게시글 삭제 (DELETE /posts/<id>)
  12. 마무리

실습_블로그 구현 (Flask-MySQL를 활용)

이번 실습에서는 Flask와 MySQL을 활용하여 간단한 블로그 시스템을 구현합니다. 블로그 시스템은 사용자에게 게시물을 생성, 조회, 수정 및 삭제할 수 있는 기능을 제공합니다. 아래에서는 전체 코드를 제시한 후, 각 프로세스를 단계별로 설명하겠습니다.

프로젝트 구조

my_flask_app/
│
├── app.py                # Flask 애플리케이션 설정 및 라우팅
├── posts_routes.py       # 게시물 관련 라우트 처리
├── db.yaml               # 데이터베이스 연결 정보
└── templates/
    ├── posts.html        # 게시물 리스트 및 작성 폼
    └── post.html         # 개별 게시물 표시

 

이번 코드는 게시글 CRUD (생성, 조회, 수정, 삭제) 기능을 제공하는 API의 라우트와 뷰 함수를 구현한 부분입니다. 이를 위해 Flask와 Flask-Smorest를 사용하여 RESTful API 스타일로 작성되었으며, MySQL 데이터베이스와의 상호작용을 위해 Flask-MySQLdb를 사용하고 있습니다.

아래는 각 기능을 단계별로 설명한 내용입니다.

전체 코드 (posts_routes.py)

from flask import request, jsonify
from flask_smorest import Blueprint, abort


def create_posts_blueprint(mysql):
    posts_blp = Blueprint(
        "posts",
        __name__,
        description="posts api",
        url_prefix="/posts",
    )

    # 게시글 목록 조회 및 생성
    @posts_blp.route("/", methods=["GET", "POST"])
    def posts():
        cursor = mysql.connection.cursor()

        # 게시글 조회
        if request.method == "GET":
            sql = "SELECT * FROM posts"
            cursor.execute(sql)

            posts = cursor.fetchall()
            cursor.close()

            post_list = []

            for post in posts:
                post_list.append(
                    {
                        "id": post[0],
                        "title": post[1],
                        "content": post[2],
                    }
                )
            return jsonify(post_list)

        # 게시글 생성
        elif request.method == "POST":
            title = request.json.get("title")
            content = request.json.get("content")

            if not title or not content:
                abort(400, message="title 또는 content가 없습니다.")

            sql = "INSERT INTO posts(title, content) VALUES(%s, %s)"
            cursor.execute(sql, (title, content))
            mysql.connection.commit()

            return jsonify({"message": "success"}), 201

    # 게시글 상세 조회, 수정 및 삭제
    @posts_blp.route("/<int:id>", methods=["GET", "PUT", "DELETE"])
    def post(id):
        cursor = mysql.connection.cursor()

        # 게시글 상세 조회
        if request.method == "GET":
            sql = f"SELECT * FROM posts WHERE id={id}"
            cursor.execute(sql)
            post = cursor.fetchone()

            if not post:
                abort(404, message="해당 게시글이 없습니다.")
            return {
                "id": post[0],
                "title": post[1],
                "content": post[2],
            }

        # 게시글 수정
        elif request.method == "PUT":
            title = request.json.get("title")
            content = request.json.get("content")

            if not title or not content:
                abort(400, message="title 또는 content가 없습니다.")

            sql = "SELECT * FROM posts WHERE id=%s"
            cursor.execute(sql, (id,))
            post = cursor.fetchone()

            if not post:
                abort(404, message="해당 게시글이 없습니다.")

            sql = "UPDATE posts SET title=%s, content=%s WHERE id=%s"
            cursor.execute(sql, (title, content, id))
            mysql.connection.commit()

            return jsonify({"message": "Successfully updated title & content"})

        # 게시글 삭제
        elif request.method == "DELETE":
            sql = "SELECT * FROM posts WHERE id=%s"
            cursor.execute(sql, (id,))
            post = cursor.fetchone()

            if not post:
                abort(404, message="해당 게시글이 없습니다.")

            sql = "DELETE FROM posts WHERE id=%s"
            cursor.execute(sql, (id,))
            mysql.connection.commit()

            return jsonify({"message": "Successfully deleted post"})

    return posts_blp

1. create_posts_blueprint 함수

이 함수는 Flask 애플리케이션에서 사용할 블루프린트를 정의합니다. 블루프린트는 Flask에서 여러 개의 라우트를 그룹화하여 모듈화할 수 있게 해주는 기능입니다. 이 함수는 mysql 객체를 받아 게시글 관련 라우트를 설정합니다.

Blueprint 설정

posts_blp = Blueprint(
    "posts",
    __name__,
    description="posts api",
    url_prefix="/posts",
)
  • Blueprint: "posts"라는 이름의 블루프린트를 생성하고, /posts라는 URL 프리픽스를 설정합니다. 이후 이 블루프린트에 정의된 모든 라우트는 /posts로 시작합니다.

2. GET 및 POST 요청 처리

게시글 목록 조회 (GET /posts)

@posts_blp.route("/", methods=["GET", "POST"])
def posts():
    cursor = mysql.connection.cursor()

    if request.method == "GET":
        sql = "SELECT * FROM posts"
        cursor.execute(sql)
        posts = cursor.fetchall()
        cursor.close()

        post_list = []

        for post in posts:
            post_list.append(
                {
                    "id": post[0],
                    "title": post[1],
                    "content": post[2],
                }
            )
        return jsonify(post_list)
  • 목표: MySQL 데이터베이스에서 모든 게시글을 조회하여 JSON 형식으로 반환합니다.
  • 동작:
    • GET 요청 시, SELECT * FROM posts 쿼리를 실행하여 모든 게시글을 조회합니다.
    • 조회된 게시글들을 post_list에 담고, 이를 jsonify로 JSON 형태로 반환합니다.

게시글 생성 (POST /posts)

elif request.method == "POST":
    title = request.json.get("title")
    content = request.json.get("content")

    if not title or not content:
        abort(400, message="title 또는 content가 없습니다.")

    sql = "INSERT INTO posts(title, content) VALUES(%s, %s)"
    cursor.execute(sql, (title, content))
    mysql.connection.commit()

    return jsonify({"message": "success"}), 201
  • 목표: 클라이언트로부터 게시글의 제목과 내용을 받아 새로운 게시글을 생성합니다.
  • 동작:
    • POST 요청 시, 요청 본문에서 title과 content 값을 받아옵니다.
    • 제목 또는 내용이 없으면 400 상태 코드와 함께 오류 메시지를 반환합니다.
    • INSERT INTO posts 쿼리를 실행하여 게시글을 추가하고, 변경 사항을 커밋한 후 성공 메시지를 반환합니다.

3. 게시글 상세 조회, 수정, 삭제 (GET /posts/<int:id>, PUT /posts/<int:id>, DELETE /posts/<int:id>)

게시글 상세 조회 (GET /posts/<id>)

@posts_blp.route("/<int:id>", methods=["GET", "PUT", "DELETE"])
def post(id):
    cursor = mysql.connection.cursor()

    if request.method == "GET":
        sql = f"SELECT * FROM posts WHERE id={id}"
        cursor.execute(sql)
        post = cursor.fetchone()

        if not post:
            abort(404, message="해당 게시글이 없습니다.")
        return {
            "id": post[0],
            "title": post[1],
            "content": post[2],
        }
  • 목표: 특정 게시글을 조회합니다.
  • 동작:
    • GET 요청 시, SELECT * FROM posts WHERE id={id} 쿼리를 실행하여 특정 게시글을 조회합니다.
    • 해당 게시글이 없으면 404 오류를 반환하고, 존재하면 게시글 데이터를 JSON 형식으로 반환합니다.

게시글 수정 (PUT /posts/<id>)

elif request.method == "PUT":
    title = request.json.get("title")
    content = request.json.get("content")

    if not title or not content:
        abort(400, message="title 또는 content가 없습니다.")

    sql = "SELECT * FROM posts WHERE id=%s"
    cursor.execute(sql, (id,))
    post = cursor.fetchone()

    if not post:
        abort(404, message="해당 게시글이 없습니다.")

    sql = "UPDATE posts SET title=%s, content=%s WHERE id=%s"
    cursor.execute(sql, (title, content, id))
    mysql.connection.commit()

    return jsonify({"message": "Successfully updated title & content"})
  • 목표: 특정 게시글의 제목과 내용을 수정합니다.
  • 동작:
    • PUT 요청 시, 요청 본문에서 title과 content 값을 받아옵니다.
    • 해당 게시글이 존재하지 않으면 404 오류를 반환합니다.
    • 게시글이 존재하면 UPDATE 쿼리를 실행하여 제목과 내용을 수정하고, 성공 메시지를 반환합니다.

게시글 삭제 (DELETE /posts/<id>)

elif request.method == "DELETE":
    sql = "SELECT * FROM posts WHERE id=%s"
    cursor.execute(sql, (id,))
    post = cursor.fetchone()

    if not post:
        abort(404, message="해당 게시글이 없습니다.")

    sql = "DELETE FROM posts WHERE id=%s"
    cursor.execute(sql, (id,))
    mysql.connection.commit()

    return jsonify({"message": "Successfully deleted post"})
  • 목표: 특정 게시글을 삭제합니다.
  • 동작:
    • DELETE 요청 시, 해당 게시글이 존재하지 않으면 404 오류를 반환합니다.
    • 존재하면 DELETE 쿼리를 실행하여 게시글을 삭제하고, 성공 메시지를 반환합니다.

마무리

이 코드는 게시글 CRUD 기능을 제공하는 API의 라우트와 뷰 함수입니다. Flask의 Blueprint를 사용하여 게시물 관련 라우트를 모듈화하고, MySQL 데이터베이스와 상호작용하여 게시물을 생성, 조회, 수정 및 삭제할 수 있게 구현했습니다. Flask-Smorest의 abort 함수를 사용하여 유효하지 않은 요청에 대한 오류 처리를 하고, 각 요청에 대해 적절한 HTTP 상태 코드와 메시지를 반환합니다.

'Flask' 카테고리의 다른 글

Chapter 4-8 HTTP 기본 인증 Basic Authentication, Flask-HTTPAuth  (0) 2025.04.22
Chapter 4-7 Flask Authentication/ Session 인증 방식  (0) 2025.04.22
Chapter 4-4 실습_블로그 구현 (Flask-MySQL를 활용) MySQL 쿼리, db.yaml  (0) 2025.04.22
Chapter 4-3 실습_블로그 구현 (Flask-MySQL를 활용) templates/posts.html  (0) 2025.04.22
Chapter 4-2 실습_블로그 구현 (Flask-MySQL를 활용)  (0) 2025.04.22
  1. 프로젝트 구조
  2. 전체 코드 (posts_routes.py)
  3. 1. create_posts_blueprint 함수
  4. Blueprint 설정
  5. 2. GET 및 POST 요청 처리
  6. 게시글 목록 조회 (GET /posts)
  7. 게시글 생성 (POST /posts)
  8. 3. 게시글 상세 조회, 수정, 삭제 (GET /posts/<int:id>, PUT /posts/<int:id>, DELETE /posts/<int:id>)
  9. 게시글 상세 조회 (GET /posts/<id>)
  10. 게시글 수정 (PUT /posts/<id>)
  11. 게시글 삭제 (DELETE /posts/<id>)
  12. 마무리
'Flask' 카테고리의 다른 글
  • Chapter 4-8 HTTP 기본 인증 Basic Authentication, Flask-HTTPAuth
  • Chapter 4-7 Flask Authentication/ Session 인증 방식
  • Chapter 4-4 실습_블로그 구현 (Flask-MySQL를 활용) MySQL 쿼리, db.yaml
  • Chapter 4-3 실습_블로그 구현 (Flask-MySQL를 활용) templates/posts.html
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (802)
      • Python (32)
      • 프로젝트 (115)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (41)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (154)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    chatgpterror
    newpoliticalparty
    americanlaw
    btsdischarge
    classaction
    remittance
    titaniumcase
    livebroadcast
    americaparty
    urbantrends
    trumpmuskclash
    chinanightlife
    college reunions
    youngprofessionals
    lawsuitculture
    btsjungkook
    hotcoffeecase
    travel ban
    bts
    RM
    basalcellcarcinoma
    life reflection
    self-growth
    뷔
    btscomeback
    global politics
    smartphonedurability
    gpterror
    homebartrend
    btsreunion
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
Chapter 4-6 실습_블로그 구현 (Flask-MySQL를 활용) posts_routes.py

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.